Android 图片下载或上传时请求失败。

项目场景:

Android开发时使用OkHttp等相关网络框架与后端完成网络通信,完成上传或下载图片功能。



Bug1:

通过Intent获取图片,并使用OkHttp将其传输到后端,发现后端未收到Http请求(即请求丢失)。进而导致OkHttp中onResponse回调发生异常情况,发生返回数据丢失等情况。


原因分析:

发送的图片过大,导致OkHttp未能将请求发送出去。
(不知道是不是根本原因,但将图片发送前进行压缩确实能完成正常的请求发送)


解决方案:

发送前将图片等文件进行压缩,压缩完成后再将其加入到RequestsBody中进行数据发送。
并且使用Android传输大尺寸图片也是毫无意义的,因为Android本身也并不能显示出那些动辄上十兆的图片。
在此提供一个相对好用的文件压缩第三方库:Compressor



Bug2:

利用OkHttp请求图片,并将其加载到ImageView中时图片不能显示。
通常伴随相关错误或警告:

  • Failed to create image decoder with message 'unimplemented'
  • android.graphics.ImageDecoder$DecodeException: Failed to create image decoder with message 'unimplemented'Input contained an error.

实际上在开发时你很可能看不到第二个错误,而只会在网络请求回调执行中图片加载不出来时看到第一种形式的警告(这个警告极其不显眼,一般情况下你甚至不会注意到它)。两种形式对应的是同一种错误。


原因分析:

请求返回的数据流过大,直接使用该数据流生成Bitmap格式的图片生成失败。(可能原因)


解决方案:

不要直接调用BitmapFactory.decodeStream(stream),而是先将返回的数据流保存到本地文件 (若接收的是图片,则保存时最好对其进行压缩),并通过调用本地文件的Uri来使用其数据。

可在回调中尝试如下方案:

	val call = client.newCall(request)
    call.enqueue(object : Callback {
        // UI的更新需要在UI线程中更新, runOnUiThread
        override fun onFailure(call: Call?, e: IOException?) {
            e?.printStackTrace()
            activity?.runOnUiThread {
                Toast.makeText(context, "照片处理失败,请稍后重试", Toast.LENGTH_SHORT).show()
                loadingDialog.dismiss()
            }
        }

        override fun onResponse(call: Call?, response: Response) {
            val stream = response.body()!!.byteStream()
            val fType = context.contentResolver.getType(img.toUri()) ?: "jpg"
            // 将数据流保存到本地,最好同时对其进行压缩处理
            val bitmap: File = streamToFile(context, stream, fType)
            activity?.runOnUiThread {
                view?.findViewById<ImageView>(R.id.imageView)?.setImageURI(bitmap.toUri())
                Toast.makeText(context, "照片处理完成", Toast.LENGTH_SHORT).show()
                loadingDialog.dismiss()
            }
        }
    })
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值