这是我参与「第四届青训营 」笔记创作活动的的第5天.
OkHttp介绍
OkHttp是一个轻量级的开源网络库,用来处理HTTP网络请求。被很多的Android App作为网络处理的选项。
在OkHttp出现以前,也有Android自带的HttpURLConnection,不过对比这个实在是繁琐,还得自己构建异步请求。
简单使用
首先把OkHttp加入项目的Gradle依赖,往build.gradle的dependencies里加入一行
implementation 'com.squareup.okhttp:okhttp:2.7.5'
后面的版本号可以改成最新的版本。
OkHttp的基本使用如下
val client : OkHttpClient = OkHttpClient.Builder().
connectTimeout(30,TimeUnit.SECONDS).build()
val request = Request.Builder().url(targetURL).get().build()
val call : Call = OkHttpClient().newCall(request)
首先,先创建了一个OkHttpClient。这路通过Builder的形式创建,设置了链接超时时间为30秒,除此之外,还可以设置代理,缓存策略,添加拦截器等。
再构建了一个Request,设置请求方法为get,设置请求的URL地址。
对于Post请求,只需要如下改动
val formBody : FormBody = FormBody.Builder().add("Key","Value").add("head","stirng")
request = Request.Builder().url(targetURL).post(formBody).build()
最后把这个Request封装为一个Call。
接着来进行请求操作
call.enqueue(object : Callback{
override fun onFailure(call: Call, e: IOException) {
Log.e("HTTP","Fail when making call")
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
//Do Something
}
call.enqueue代表着进行一个异步请求。这个方法需要传入一个CallBack接口的实现。当请求成功,会调用接口的onResponse,反之,调用onFailure。
如果想要调用同步请求,那么把enqueue换成excute就可以了。
简单实践——制作一个网图显示器
成品效果

在一个TextEdit里输入一张图片的网址,再按下按钮,就能把图片显示在下面了。
就比如演示里那个Projection Matrix,这是我目前唯一能找到的图片了
图片地址s2.loli.net/2022/08/05/…
制作
新建一个MainActivity,再来个Layout。
Layout的样式随意,反正一个输入框,一个按钮,一个图片显示器
这次由于需要联网,所以先得到manifest里添加联网权限。
<uses-permission android:name="android.permission.INTERNET"/>
如果不添加的话会直接报错闪退的hhh
在MainActivity里构造一个MainActivityBinding,并且拿到一系列的控件
var binding: ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater)
val button = binding.button
val textEdit = binding.textEdit
val imageViewer = binding.imageViewer
对这个Button添加点击事件。
binding.button.setOnClickListener{
val client : OkHttpClient = OkHttpClient.Builder().connectTimeout(30,TimeUnit.SECONDS).build()
val str = binding.editText.text.toString()
var request : Request
request = Request.Builder().url(str).get().build()
val call : Call = OkHttpClient().newCall(request)
call.enqueue(object : Callback{
override fun onFailure(call: Call, e: IOException) {
Log.e("HTTP","Fail when making call")
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
val mStream : InputStream? = response.body()?.byteStream()
if(bitmap != null){
val bitmap = BitmapFactory.decodeStream(mStream)
runOnUiThread {
binding.imageView.setImageBitmap(bitmap)
}
}
}
})
}
逻辑非常简单,就是构建了一个请求,然后异步请求了图片资源,把图片资源转换成了输入二进制流,然后利用BitmapFactory构造了一个图片。
当然,如果只是想拿到请求体的内容并且显示在某个TextView上,也可以使用
val str = response.body().string()
通过这个语句就能获取到网页的HTML内容或者Json。
但是注意,这里一定要使用 runOnUiThread来更新视图,enqueue事实上是利用了多线程异步,而UI只能在主线程更新。