Android进阶:6、使用okhttp下载图片
创始人
2024-02-13 07:48:11
0

因为在网上找到的资源不只是一些字符串或是一些二进制数字,还是有的是可以肉眼看见的图片,那么我们在发送网络请求时拿到的是一张图片该如何显示在组件上面呢?

这就要使用到okhttp的请求返回结果的一个属性(byteStream):

var input = result.byteStream()
bitmap=BitmapFactory.decodeStream(input)
myhanlder.sendEmptyMessage(3)

结合之前学习的通过okhttp发送get异步请求方式,可以写出这样的代码:

 OkhttpUtils.get().doGet(url,object :NetWorkCallBack{override fun onSuccess(result: ResponseBody) {//TODO("Not yet implemented")var input = result.byteStream()bitmap=BitmapFactory.decodeStream(input)myhanlder.sendEmptyMessage(3)}override fun onFail(msg: String) {//TODO("Not yet implemented")Toast.makeText(this@Okhttp,"请求失败",Toast.LENGTH_SHORT).show()}})

这里的OkhttpUtils是经过了封装的类,所以才有两个结果状态函数(onSuccess和onFail):

1、请求的封装

之前使用这个框架的时候我使用了很多的方法,有get、json、表单,现在又有一个图片的下载,所以我就直接讲这些请求方法封装在了一个工具类里面,这里面是这样写的:

package com.example.hanlderpractice.serviceimport com.example.hanlderpractice.entity.NetWorkCallBack
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONObject
import java.io.IOException
import java.util.concurrent.TimeUnitclass OkhttpUtils public constructor() {companion object {private var instance: OkhttpUtils? = nullget() {if (field == null) {field = OkhttpUtils()}return field}fun get(): OkhttpUtils {return instance!!}}private var client:OkHttpClient?=nullinit {client=OkHttpClient.Builder().readTimeout(5,TimeUnit.SECONDS).connectTimeout(5,TimeUnit.SECONDS).build()}fun doGet(url:String,netWorkCallBack: NetWorkCallBack):Unit{var request=Request.Builder().url(url).build()client?.newCall(request)?.enqueue(object :Callback{override fun onFailure(call: Call, e: IOException) {//TODO("Not yet implemented")netWorkCallBack.onFail("请求失败")}override fun onResponse(call: Call, response: Response) {//TODO("Not yet implemented")netWorkCallBack.onSuccess(response.body!!)}})}fun doJson(url:String,jsonobject:JSONObject,netWorkCallBack: NetWorkCallBack):Unit{var jsonstr=jsonobject.toString().toRequestBody("application/json;charset=utf-8".toMediaType())var request: Request=Request.Builder().url(url).post(jsonstr).build()client?.newCall(request)?.enqueue(object :Callback{override fun onFailure(call: Call, e: IOException) {//TODO("Not yet implemented")netWorkCallBack.onFail("请求失败")}override fun onResponse(call: Call, response: Response) {//TODO("Not yet implemented")netWorkCallBack.onSuccess(response.body!!)}})}fun doForm(url:String,formBody:FormBody,netWorkCallBack: NetWorkCallBack):Unit{var request: Request=Request.Builder().url(url).post(formBody).build()client?.newCall(request)?.enqueue(object :Callback{override fun onFailure(call: Call, e: IOException) {//TODO("Not yet implemented")netWorkCallBack.onFail("请求失败")}override fun onResponse(call: Call, response: Response) {//TODO("Not yet implemented")netWorkCallBack.onSuccess(response.body!!)}})}
}

通过派生对象来重写这个工具类的get方法,使他只能够实例化一次,也就是常见的单例模式;

还有一个对象就是用来存储请求到的数据的接口,所以这两个返回结果状态函数是这个接口里面的:

package com.example.hanlderpractice.entityimport okhttp3.ResponseBodyinterface NetWorkCallBack {public fun onSuccess(result:ResponseBody)public fun onFail(msg:String)
}

这是一个接口,我在调用了发送请求的方法之后就会拿到一个请求结果对象,于是我就将这个结果(工具类请求到的数据)丢在这个接口里面,我就可以再别的地方(调用工具类请求方法的类)拿到了:

var url="http://119.img.pp.sohu.com/images/blog/2007/9/28/18/15/115e6595d75.jpg"OkhttpUtils.get().doGet(url,object :NetWorkCallBack{override fun onSuccess(result: ResponseBody) {//TODO("Not yet implemented")var input = result.byteStream()bitmap=BitmapFactory.decodeStream(input)myhanlder.sendEmptyMessage(3)}

就比如这里,这里使用了工具类里面的doGEt方法,而且第二个参数就是这个接口,他的成功函数里面的参数就是请求到的数据体,这时候直接创建他的字节流然后转化成bitmap对象设置到imageview组件上就可以实现图片的展示了,当然如果不是发送很多请求的话也可以直接发送get请求不用封装,这里是一样的效果的,到时候拿到数据体的字节流就可以转化为bitmap对象了;

其他的post表单请求可以同样的方法,通过这个接口来返回这个数据体;

2、设置图片

//创建弱引用handlerprivate class MyHanlder(var wk: WeakReference): Handler(Looper.getMainLooper()){override fun handleMessage(msg: Message) {super.handleMessage(msg)wk.get()?.run {if(msg.what==1){Toast.makeText(this,"登录成功", Toast.LENGTH_SHORT).show()var intent: Intent = Intent(this,MainActivity::class.java)startActivity(intent)}else if(msg.what==2){}else if(msg.what==3){iv_header.setImageBitmap(bitmap);}else{Toast.makeText(this,"登录失败", Toast.LENGTH_SHORT).show()}}}}

同样的,发送请求只能在子线程,而更新界面需要发送消息,这里就是what=3的时候的消息,于是将这个通过网络数据构建成的bitmap设置到组件上面;

无论是哪一张图片,这里是样例,也可以是其他的照片,可以使用同样的方式来显示到组件上;

 

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...