首先需要异步方式从服务器下载这个图片,也就是从服务器获取图片流,从服务器获取流的细节具体可看《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]