【Android】HttpURLConnection、OkHttp

WebView 已经在后台帮我们处理好了发送HTTP请求、接收服务器响应、解析返回数据,以及最终的页面展示这几步工作。只不过它封装得实在是太好了,反而使得我们不能那么直观地看出HTTP到底是如何工作的。因此,接下来我们通过手动发送HTTP请求的方式,更加深入地理解这个过程。

在过去,Android上发送HTTP请求一般有两种方式:HttpURLConnection 和HttpClient 。不过由于HttpClient 存在API数量过多、扩展困难等缺点,Android团队越来越不建议我们使用这种方式。终于在Android 6.0 系统中,HttpClient 的功能被完全移除了,标志着此功能被正式弃用。

现在,官方建议使用的HttpURLConnection

HttpURLConnection

kt 复制代码
class MainActivity : AppCompatActivity() {
	override fun onCreate(savedInstanceState: Bundle?) { 
		super.onCreate(savedInstanceState) 
		setContentView(R.layout.activity_main) 
		
		sendRequestBtn.setOnClickListener {
			sendRequestWithHttpURLConnection() 
		}
	}
	/**
	在这个方法中先是开启了一个子线程,然后在子线程里使用HttpURLConnection 发出一条HTTP请求。
	*/
	private fun sendRequestWithHttpURLConnection() { // 开启线程发起网络请求
		thread {
			var connection: HttpURLConnection? = null 
			try {
				val response = StringBuilder()
				//首先,需要获取HttpURLConnection 的实例,一般只需创建一个URL对象,并传入目标的网络地 址
				val url = URL("https://www.baidu.com")
				//然后,调用一下openConnection()方法即可
				connection = url.openConnection() as HttpURLConnection 
				
				//设置:HTTP请求所使用的方法、连接超时、读取超时的毫秒数
				connection.requestMethod = "GET"
				connection.connectTimeout = 8000 
				connection.readTimeout = 8000
				
				//之后,再调用getInputStream()方法就可以获取到服务器返回的输入流了
				val input = connection.inputStream
				
				//接着利用BufferedReader 对服务器返回的流进行读取
				val reader = BufferedReader(InputStreamReader(input)) 
				reader.use {
					reader.forEachLine {
						response.append(it) 
					}
				}
				//将结果传入showResponse() 方法中。
				showResponse(response.toString()) 
			} catch (e: Exception) {
				e.printStackTrace() 
			} finally {
				connection?.disconnect() 
			}
		} 
	}
	private fun showResponse(response: String) { 
		runOnUiThread {
			// 在这里进行UI操作,将结果显示到界面上
			responseText.text = response 
		}
	}
}
xml 复制代码
<!-- AndroidManifest.xml 声明一下网络权限-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
	package="com.example.networktest">
	<uses-permission android:name="android.permission.INTERNET" />
    ...
</manifest>
xml 复制代码
<!-- activity_main.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
	android:orientation="vertical"
	android:layout_width="match_parent" 
	android:layout_height="match_parent" >
	
	<Button
	android:id="@+id/sendRequestBtn" 
	android:layout_width="match_parent" 
	android:layout_height="wrap_content" 
	android:text="Send Request" />
	
	<ScrollView 
		android:layout_width="match_parent" 
		android:layout_height="match_parent" >
		
		<TextView
		android:id="@+id/responseText" 
		android:layout_width="match_parent" 
		android:layout_height="wrap_content" />
		
	</ScrollView>
	
</LinearLayout>

提交数据给服务器:

kt 复制代码
connection.requestMethod = "POST"
val output = DataOutputStream(connection.outputStream) output.writeBytes("username=admin&password=123456")

OkHttp

js 复制代码
dependencies {
    ...
	implementation 'com.squareup.okhttp3:okhttp:4.1.0' 
}

下面我们来看一下OkHttp 的具体用法。

首先,需要创建一个OkHttpClient的实例,如下所示:

kt 复制代码
val client = OkHttpClient()

接下来如果想要发起一条HTTP请求,就需要创建一个Request对象:

kt 复制代码
val request = Request.Builder().build()

当然,上述代码只是创建了一个空的Request对象,并没有什么实际作用,我们可以在最终的 build()方法之前连缀很多其他方法来丰富这个Request对象。比如,可以通过url()方法来设置目标的网络地址,如下所示:

kt 复制代码
val request = Request.Builder()
		.url("https://www.baidu.com")
		.build()

之后调用OkHttpClient 的newCall()方法来创建一个Call对象,并调用它的execute()方法 来发送请求并获取服务器返回的数据,写法如下:

kt 复制代码
val response = client.newCall(request).execute()

Response对象就是服务器返回的数据了,我们可以使用如下写法来得到返回的具体内容:

kt 复制代码
val responseData = response.body?.string()

如果是发起一条POST请求,会比GET请求稍微复杂一点,我们需要先构建一个Request Body 对象来存放待提交的参数,如下所示:

kt 复制代码
val requestBody = FormBody.Builder() 
		.add("username", "admin")
		.add("password", "123456") 
		.build()

然后在Request.Builder 中调用一下post()方法,并将RequestBody对象传入:

kt 复制代码
val request = Request.Builder() 
		.url("https://www.baidu.com")
		.post(requestBody) 
		.build()

接下来的操作就和GET请求一样了,调用execute()方法来发送请求并获取服务器返回的数据即可。

相关推荐
雨白4 小时前
Jetpack系列(二):Lifecycle与LiveData结合,打造响应式UI
android·android jetpack
kk爱闹6 小时前
【挑战14天学完python和pytorch】- day01
android·pytorch·python
每次的天空8 小时前
Android-自定义View的实战学习总结
android·学习·kotlin·音视频
恋猫de小郭8 小时前
Flutter Widget Preview 功能已合并到 master,提前在体验毛坯的预览支持
android·flutter·ios
断剑重铸之日9 小时前
Android自定义相机开发(类似OCR扫描相机)
android
随心最为安9 小时前
Android Library Maven 发布完整流程指南
android
岁月玲珑9 小时前
【使用Android Studio调试手机app时候手机老掉线问题】
android·ide·android studio
还鮟13 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡15 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi0015 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体