【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()方法来发送请求并获取服务器返回的数据即可。

相关推荐
tran_sient几秒前
【Android】制造一个ANR并进行简单分析
android·anr
前行的小黑炭32 分钟前
Android Flow:你真的了解?在工作当中的运用~~通过光照例子来解释一下..
android·kotlin
tangweiguo0305198744 分钟前
极致效率:用 Copilot 加速你的 Android 开发
android·copilot
阿华的代码王国1 小时前
【Android】Room数据库的使用
android·数据库·room
lichong9511 小时前
【混合开发】Android+Webview+VUE播放视频之视频解析工具mediainfo-Macos
android·macos·架构·vue·音视频·api·postman
翻滚丷大头鱼7 小时前
android View详解—View的刷新流程源码解析
android
zhangphil8 小时前
Android adb shell命令分析应用内存占用
android·adb
漠缠9 小时前
Android AI客户端开发(语音与大模型部署)面试题大全
android·人工智能
Lei活在当下10 小时前
一个基础问题:关于SDK初始化时机的选择
android
雨白12 小时前
Android 触摸反馈与事件分发原理解析
android