Android - kotlin simple package network request OkHttp

1. The okhttp library

dependencies {
 ...
 implementation 'com.squareup.okhttp3:okhttp:4.1.0'
}

First you need to create an instance of OkHttpClient

val client = OkHttpClient()

Next, if you want to initiate an HTTP request, you need to create a Request object:

val request = Request.Builder().build() 

Many other methods are added before the final build() method to enrich the Request object. For example, the network address of the target can be set by the url() method

val request = Request.Builder()
 .url("https://www.baidu.com")
 .build()

 Then call the newCall() method of OkHttpClient to create a Call object, and call its execute() method to send the request and get the data returned by the server

val response = client.newCall(request).execute()

The Response object is the data returned by the server. We can use the following writing method to get the specific content returned

val responseData = response.body?.string() 

POST requests are a little more complicated than GET requests. We need to build a Request Body object to store the parameters to be submitted.

val requestBody = FormBody.Builder()
 .add("username", "admin")
 .add("password", "123456")
 .build()

 Then call the post() method in Request.Builder and pass in the RequestBody object

val request = Request.Builder()
 .url("https://www.baidu.com")
 .post(requestBody)
 .build()

 The next operation is the same as the GET request, just call the execute() method to send the request and get the data returned by the server.

use:

class MainActivity : AppCompatActivity() {
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)
 sendRequestBtn.setOnClickListener {
 sendRequestWithOkHttp()
 }
 }
 ...
 private fun sendRequestWithOkHttp() {
 thread {
 try {
 val client = OkHttpClient()
 val request = Request.Builder()
 .url("https://www.baidu.com")
 .build()
 val response = client.newCall(request).execute()
 val responseData = response.body?.string()
 if (responseData != null) {
 showResponse(responseData)
 }
 } catch (e: Exception) {
 e.printStackTrace()
 }
 }
 }
}

2. Implementation of network request callback

An application is likely to use network functions in many places, and the code for sending HTTP requests is basically the same. If we write the code for sending HTTP requests every time, this is obviously a very bad practice, which can be encapsulated

object HttpUtil {
 ...
 fun sendOkHttpRequest(address: String, callback: okhttp3.Callback) {
 val client = OkHttpClient()
 val request = Request.Builder()
 .url(address)
 .build()
 client.newCall(request).enqueue(callback)
 
}
 }
 // 回调onFinish()方法
 listener.onFinish(response.toString())
 } catch (e: Exception) {
 e.printStackTrace()
 // 回调onError()方法
 listener.onError(e)
 } finally {
 connection?.disconnect()
 }
 }
 }
}

Two methods are defined in the interface: the onFinish() method means that it is called when the server successfully responds to our request, and the onError() means that it is called when an error occurs in the network operation. These two methods have parameters, the parameters in the onFinish() method represent the data returned by the server, and the parameters in the onError() method record the detailed information of the error. 

interface HttpCallbackListener {
 fun onFinish(response: String)
 fun onError(e: Exception)
}

First add an HttpCallbackListener parameter to the sendHttpRequest() method, and open a sub-thread inside the method, and then perform specific network operations in the sub-thread. Note that the return statement cannot return data in the child thread, so here we pass the server response data into the onFinish() method of the HttpCallbackListener. If an exception occurs, pass the exception reason into the onError() method. Now the sendHttpRequest() method receives two parameters, so we also need to pass in the instance of HttpCallbackListener when calling it

HttpUtil.sendHttpRequest(address, object : HttpCallbackListener {
 override fun onFinish(response: String) {
 // 得到服务器返回的具体内容
 }
 override fun onError(e: Exception) {
 // 在这里对异常情况进行处理
 }
})

In this way, when the server responds successfully, we can process the response data in the onFinish() method. Similarly, if an exception occurs, the exception can be handled in the onError() method. In this way, we cleverly use the callback mechanism to successfully return the response data to the caller.

There is an okhttp3.Callback parameter in the sendOkHttpRequest() method. This is the callback interface that comes with the OkHttp library, similar to the HttpCallbackListener we just wrote. Then after client.newCall(), instead of calling the execute() method as before, it calls an enqueue() method and passes in the okhttp3.Callback parameter. I believe you have guessed the smart ones. OkHttp has opened the sub-thread for us inside the enqueue() method, and then executes the HTTP request in the sub-thread, and calls back the final request result to okhttp3.Callback. Then we can write like this when calling the sendOkHttpRequest() method

HttpUtil.sendOkHttpRequest(address, object : Callback {
 override fun onResponse(call: Call, response: Response) {
 // 得到服务器返回的具体内容
 val responseData = response.body?.string()
 }
 override fun onFailure(call: Call, e: IOException) {
 // 在这里对异常情况进行处理
 }
})

It should be noted that whether using HttpURLConnection or OkHttp, the final callback interface is still running in the child thread, so we cannot perform any UI operations here, unless the thread conversion is performed with the help of the runOnUiThread() method

Next: How to use Retrofit

Guess you like

Origin blog.csdn.net/m0_59482482/article/details/129951755