目录
概述
get请求
post请求
post文件上传
post上传字符串
概述
第一步,app/build.gradle里添加okhttp3的依赖,分为Okhttp,和logging-interceptor
// define a BOM and its versionimplementation(platform("com.squareup.okhttp3:okhttp-bom:4.10.0"))// define any required OkHttp artifacts without versionimplementation("com.squareup.okhttp3:okhttp")implementation("com.squareup.okhttp3:logging-interceptor")
第二步,AndroidManifest.xml里添加网络权限
<uses-permission android:name="android.permission.INTERNET">
</uses-permission>
第三步,新建网络请求类Hiokhttp
get请求
- 通过OkHttpClient构造client对象
- 通过Request.Builder构建一个request实例(要在子线程里完成)
- 通过client.newCall构建Call实例
- 通过call.execute发起同步请求/通过call.enqueue发起异步请求
- 通过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 {//构造请求体requestval 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(){//构造请求体requestval 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")}})}