- import android.graphics.Bitmap
- import android.os.Bundle
- import android.util.Log
- import android.widget.ImageView
- import androidx.appcompat.app.AppCompatActivity
- import androidx.lifecycle.lifecycleScope
- import com.bumptech.glide.load.DataSource
- import com.bumptech.glide.load.engine.GlideException
- import com.bumptech.glide.load.resource.bitmap.CenterCrop
- import com.bumptech.glide.request.RequestListener
- import com.bumptech.glide.request.target.Target
- import kotlinx.coroutines.Dispatchers
- import kotlinx.coroutines.channels.Channel
- import kotlinx.coroutines.flow.receiveAsFlow
- import kotlinx.coroutines.launch
-
-
- class MainActivity : AppCompatActivity() {
- private val TAG = "Glide/${this::class.simpleName}"
-
- companion object {
- const val FAIL = -1
- const val SUCCESS = 1
- const val SIZE = 400
- }
-
- private val mCrop = CenterCrop()
- private val resId = R.mipmap.pic2
- private var mImageView: ImageView? = null
-
- private val mChannel = Channel<Int>()
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
-
- val imageView = findViewById
(R.id.image) - mImageView = findViewById(R.id.image2)
-
- GlideApp.with(this)
- .asBitmap()
- .load(resId)
- .transform(mCrop)
- .override(SIZE, SIZE)
- .addListener(object : RequestListener
{ - override fun onLoadFailed(
- e: GlideException?,
- model: Any?,
- target: Target<Bitmap>,
- isFirstResource: Boolean
- ): Boolean {
- Log.d(TAG, "onLoadFailed")
- signal(FAIL)
- return false
- }
-
- override fun onResourceReady(
- resource: Bitmap,
- model: Any,
- target: Target<Bitmap>?,
- dataSource: DataSource,
- isFirstResource: Boolean
- ): Boolean {
- Log.d(TAG, "onResourceReady")
- signal(SUCCESS)
- return false
- }
- }).into(imageView)
-
- waitReceive()
- }
-
- fun signal(s: Int) {
- lifecycleScope.launch(Dispatchers.IO) {
- mChannel.send(s)
- }
- }
-
- private fun waitReceive() {
- lifecycleScope.launch(Dispatchers.IO) {
- mChannel.receiveAsFlow().collect {
- Log.d(TAG, "collect $it")
-
- if (it == SUCCESS) {
- fetchCacheBitmap()
- }
- }
- }
- }
-
- private fun fetchCacheBitmap() {
- val bitmap = runCatching {
- GlideApp.with(this@MainActivity)
- .asBitmap()
- .load(resId)
- .transform(mCrop)
- .onlyRetrieveFromCache(true) //从内存或者glide decode好的resource里面取,不去原始decode
- .override(SIZE, SIZE)
- .addListener(object : RequestListener
{ - override fun onLoadFailed(
- e: GlideException?,
- model: Any?,
- target: Target<Bitmap>,
- isFirstResource: Boolean
- ): Boolean {
- Log.d(TAG, "cache onLoadFailed")
- return false
- }
-
- override fun onResourceReady(
- resource: Bitmap,
- model: Any,
- target: Target<Bitmap>?,
- dataSource: DataSource,
- isFirstResource: Boolean
- ): Boolean {
- Log.d(TAG, "cache onResourceReady")
- return false
- }
- }).submit()
- .get() //不要在这里加timeout值
- }.onFailure {
- Log.d(TAG, "取Glide缓存失败:${it.message}")
- }.onSuccess {
- Log.d(TAG, "取Glide缓存成功:${it.byteCount}")
- }.getOrNull()
-
- Log.d(TAG, "getOrNull=${bitmap?.byteCount}")
-
- if (bitmap != null) {
- lifecycleScope.launch(Dispatchers.Main) {
- //之前的缓存资源取到了。
- //使用之前的缓存,设置到新的ImageView里面。
- mImageView?.setImageBitmap(bitmap)
- }
- }
- }
- }
可以看到,第一次因为是全新的加载,没有缓存,glide只能干脏活,把原始的图片文件decode成resource,花费200+毫秒,而之后,只从缓存(包括磁盘的resource半成品)中取,仅仅花费20+毫秒,时间开销是原先的约1/10,加载速度相当于快了约10倍。