Android Gldie复用只取之前decode过的缓存resource,Kotlin

Android Gldie复用只取之前decode过的缓存resource,Kotlin

Kotlin 复制代码
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<ImageView>(R.id.image)
        mImageView = findViewById(R.id.image2)

        GlideApp.with(this)
            .asBitmap()
            .load(resId)
            .transform(mCrop)
            .override(SIZE, SIZE)
            .addListener(object : RequestListener<Bitmap> {
                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<Bitmap> {
                    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倍。

Android Glide限定onlyRetrieveFromCache取内存缓存submit超时阻塞方式,Kotlin-CSDN博客文章浏览阅读1.4k次。文章浏览阅读638次。【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬而未决:比如用户的头像,往往用户的头像是从服务器端读出的一个普通矩形图片,但是现在的设计一般要求在APP端的用户头像显示成圆形头像,那么此时虽然Glide可以加载,但加载出来的是一个矩形,如果要Glide_android 毛玻璃圆角。文章浏览阅读353次。kotlin异常处理try-catch-finally_zhangphil的博客-CSDN博客。https://blog.csdn.net/zhangphil/article/details/134051794

相关推荐
666xiaoniuzi2 小时前
深入理解 C 语言中的内存操作函数:memcpy、memmove、memset 和 memcmp
android·c语言·数据库
沐言人生6 小时前
Android10 Framework—Init进程-8.服务端属性文件创建和mmap映射
android
沐言人生6 小时前
Android10 Framework—Init进程-9.服务端属性值初始化
android·android studio·android jetpack
沐言人生7 小时前
Android10 Framework—Init进程-7.服务端属性安全上下文序列化
android·android studio·android jetpack
追光天使7 小时前
【Mac】和【安卓手机】 通过有线方式实现投屏
android·macos·智能手机·投屏·有线
小雨cc5566ru7 小时前
uniapp+Android智慧居家养老服务平台 0fjae微信小程序
android·微信小程序·uni-app
一切皆是定数8 小时前
Android车载——VehicleHal初始化(Android 11)
android·gitee
一切皆是定数8 小时前
Android车载——VehicleHal运行流程(Android 11)
android
problc8 小时前
Android 组件化利器:WMRouter 与 DRouter 的选择与实践
android·java
图王大胜9 小时前
Android SystemUI组件(11)SystemUIVisibility解读
android·framework·systemui·visibility