okhttp同步和异步请求的简单使用

目录

概述

get请求

post请求

post文件上传

post上传字符串

概述

第一步,app/build.gradle里添加okhttp3的依赖,分为Okhttp,和logging-interceptor

    // define a BOM and its version
    implementation(platform("com.squareup.okhttp3:okhttp-bom:4.10.0"))

    // define any required OkHttp artifacts without version
    implementation("com.squareup.okhttp3:okhttp")
    implementation("com.squareup.okhttp3:logging-interceptor")

第二步,AndroidManifest.xml里添加网络权限

<uses-permission android:name="android.permission.INTERNET">
</uses-permission>

第三步,新建网络请求类Hiokhttp

get请求
  1. 通过OkHttpClient构造client对象
  2. 通过Request.Builder构建一个request实例(要在子线程里完成)
  3. 通过client.newCall构建Call实例
  4. 通过call.execute发起同步请求/通过call.enqueue发起异步请求
  5. 通过response转String类型接收响应结果

同步请求execute,会阻塞线程,因此需要在子线程完成

object Hiokhttp {
    private const val TAG = "Hiokhttp"
    private var BASE_URL = "https://jsonplaceholder.typicode.com/users"
    //构造Http对象
    private var client:OkHttpClient = OkHttpClient().newBuilder()
        .connectTimeout(10L,TimeUnit.SECONDS)
        .readTimeout(10L,TimeUnit.SECONDS)
        .writeTimeout(10L,TimeUnit.SECONDS)
        .build()

    //发起同步请求
    fun getExe(){
       Thread {
           //构造请求体request
           val request = Request.Builder().url("$BASE_URL?id=2").get().build()
           //发起call请求
           val call: Call = client.newCall(request)
           //同步请求
           val response = call.execute()
           //接收返回响应
           val result = response.body?.string()
           Log.d(TAG, "result:{$result}")
       }.start()
    }

}

异步请求enqueue,无需创建子线程发起请求。

无论同步还是异步请求,onFailure、onResponse的回调都是在子线程,我们需要切换到主线程才能操作UI控件。

子线程切换的方式有handle和runOnUiThread()

//发起异步请求
    fun getEnq(){
        //构造请求体request
        val request = Request.Builder().url("$BASE_URL?id=3").get().build()
        //发起call请求
        val call: Call = client.newCall(request)
        //异步请求
        call.enqueue(object :Callback{
            override fun onFailure(call: Call, e: IOException) {
                Log.d(TAG, "onFailure IOException:{$e}")
            }
            override fun onResponse(call: Call, response: Response) {
                //接收返回响应
                val result = response.body?.string()
                Log.d(TAG, "result:{$result}")
            }

        })
post请求

post请求与get请求类似,不同在于,post方法接收的是FormBody.Builder()构造的body对象

 //post发起同步请求
    fun postExe(){
        val body: RequestBody = FormBody.Builder().add("id","1").build()
        val request = Request.Builder().url(BASE_URL).post(body).build()
        Thread(Runnable {
            val call = client.newCall(request)
            val response  = call.execute()
            val result = response.body?.string()
            Log.d(TAG,"result:{$result}")
        }).start()
    }

    //post发起异步请求
    fun postAsync(){
        val body = FormBody.Builder().add("id","2").build()
        val request = Request.Builder().url(BASE_URL).post(body).build()
        client.newCall(request).enqueue(object:Callback{
            override fun onFailure(call: Call, e: IOException) {
                Log.d(TAG, "onFailure IOException:{$e}")
            }

            override fun onResponse(call: Call, response: Response) {
                //接收返回响应
                val result = response.body?.string()
                Log.d(TAG, "result:{$result}")
            }
        })
    }
post文件上传

post文件上传,需要MultiPartBody.Builder()构造的body对象

    fun postMult() {
        val file = File(Environment.getExternalStorageDirectory(), "logo.png")
        if (!file.exists()) {
            return
        }
        val body = MultipartBody.Builder()
            .addFormDataPart("key", "value")
            .addFormDataPart("key1", "value1")
            .addFormDataPart(
                "file", "logo.png",
                file.asRequestBody("application/octet-stream".toMediaType())
            )
            .build()
        val request = Request.Builder().url("支持文件上传的接口").post(body).build()
        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                TODO("Not yet implemented")
            }

            override fun onResponse(call: Call, response: Response) {
                TODO("Not yet implemented")
            }
        })
    }
post上传字符串

post也支持上传字符串,字符串类型可以text,也可以json字符串。

    fun postString() {
        //上传json字符串
        val json = JSONObject()
            .put("key", "value")
            .put("key1", "value1").toString()
        val body = json.toRequestBody("application/json;charset=utf-8".toMediaType())
        //上传文本格式的字符串,注意MediaType类型
        val text = "text text text"
        val body1 = text.toRequestBody("text/plain;charset-utf-8".toMediaType())

        val request =
            Request.Builder().url("支持上传字符串的接口,这个字符串可以是json,也可以是text文本")
                .post(body).build()

        client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                TODO("Not yet implemented")
            }

            override fun onResponse(call: Call, response: Response) {
                TODO("Not yet implemented")
            }

        })
    }

猜你喜欢

转载自blog.csdn.net/qq_34123324/article/details/131819202