【安卓UI】ImageView显示网络图片的三种简单实现

首先需要异步方式从服务器下载这个图片,也就是从服务器获取图片流,从服务器获取流的细节具体可看《http请求》,简化步骤如下:

var connection = URL("").openConnection() as HttpURLConnection
connection.connect()
inputStream = connection.inputStream

然后如果直接这样更新ui:imageView.setImageDrawable(Drawable.createFromStream(inputStream),image1),你会发现ui渲染不能展示完整的图片,甚至是一片黑。

具体内部实现不清楚,但是经过调试发现,’inputStream = connection.inputStream’并不能从服务器一次性获取全部的图片流,甚至完全获取不到图片流,这才导致更部分ui或者全黑,可能的原因是系统有什么的默认缓存的限制。知道这个,解决方案就有了。

  • 方案一:把接收的图片流输出为手机存储器的一张图片;
  • 方案二:把全部图片流转存到一片缓存空间。

两种方案代码实现如下(kotlin):

import android.graphics.drawable.Drawable
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.widget.ImageView
import com.mapc.demo.R
import java.io.*
import java.net.HttpURLConnection
import java.net.URL

class HttpActivity : AppCompatActivity() {

    private lateinit var ivURLImage:ImageView
    private var image1 = "1.jpg"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_http)
        this.title = ""

        ivURLImage = findViewById(R.id.iv_url_image)

        var inputStream: InputStream?=null
        var byteArray:ByteArray?=null

        var handler = object : Handler() {

            override fun handleMessage(msg: Message?) {
                super.handleMessage(msg)

                //获取图片Drawable对象的两种方式
                //方案1:图片方式渲染
                //var drawable = Drawable.createFromPath(File(Environment.getExternalStorageDirectory(),image1).path)
                //方案2:流方式渲染
                var drawable = Drawable.createFromStream(ByteArrayInputStream(byteArray),image1)

                ivURLImage.setImageDrawable(drawable)
            }
        }

        Thread(Runnable {
            var connection = URL("http://192.168.1.6:8080/android/api/image/"+image1).openConnection() as HttpURLConnection
            connection.requestMethod = "GET"
            connection.connectTimeout = 3000
            connection.doInput = true
            connection.doOutput = true
            connection.setRequestProperty("accept", "*/*")
            connection.setRequestProperty("Content-Type", "*/*")
            connection.connect()

            if (connection.responseCode == 200) {
                inputStream = connection.inputStream

                // 方式2:转存全部流,然后从流渲染ui
                var byteout=ByteArrayOutputStream()
                var byte = ByteArray(200)
                var len = inputStream?.read(byte)
                while (len !=null && len != -1) {
                    byteout.write(byte, 0, len)
                    len = inputStream?.read(byte)
                }
                byteArray=byteout.toByteArray()
                connection.disconnect()

                //方式1:流输出为图片,然后从图片渲染ui。
                //var file = File(Environment.getExternalStorageDirectory(),image1)
                //var out = FileOutputStream(file)
                //val buffer = ByteArray(1024)
                //var len: Int? = inputStream?.read(buffer)
                //while (len!=null && len != -1) {
                //    out.write(buffer, 0, len)
                //    len = inputStream?.read(buffer)
                //}
                //out.flush()
                //out.close()
                //connection.disconnect()

                handler.sendEmptyMessage(1)
            } else {}
        }).start()
    }
}

注意,在此推荐glide第三方库加载图片。兼容很好,使用简单,具体可看《glide》

[完整demo]

猜你喜欢

转载自blog.csdn.net/u012995888/article/details/80272208