Android自定义AppGlideModule,DataFetcher ,ModelLoaderFactory,ModelLoader,Kotlin(1)

Android自定义AppGlideModule,DataFetcher ,ModelLoaderFactory,ModelLoader,Kotlin(1)

假设实现一个简单的功能,对传入要加载的path路径增加一定的筛选、容错或"重定向",需要自定义一个模型,基于这个模型,让Glide自动匹配模型展开加载。

复制代码
plugins {
    id 'org.jetbrains.kotlin.kapt'
}

    implementation 'com.github.bumptech.glide:glide:4.16.0'
    kapt 'com.github.bumptech.glide:compiler:4.16.0'
Kotlin 复制代码
import android.content.Context
import android.util.Log
import com.bumptech.glide.Glide
import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.Registry
import com.bumptech.glide.annotation.GlideModule
import com.bumptech.glide.module.AppGlideModule
import java.io.InputStream


@GlideModule
class MyGlideModule : AppGlideModule() {

    override fun applyOptions(context: Context, builder: GlideBuilder) {
        super.applyOptions(context, builder)
        builder.setLogLevel(Log.DEBUG)
    }

    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        super.registerComponents(context, glide, registry)

        registry.append(
            VideoCover::class.java,
            InputStream::class.java,
            VideoCoverLoaderFactory()
        )
    }
}
Kotlin 复制代码
class VideoCover {
    var path: String? = null

    constructor(path: String) {
        this.path = path
    }
}
Kotlin 复制代码
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.Bitmap.CompressFormat
import android.graphics.BitmapFactory
import android.util.Log
import com.bumptech.glide.Priority
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.data.DataFetcher
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.InputStream

class VideoCoverFetcher : DataFetcher<InputStream> {
    val TAG = "Glide/VideoCoverFetcher"

    private var model: VideoCover? = null
    private val resId = android.R.drawable.stat_notify_error

    constructor(model: VideoCover) {
        this.model = model
    }

    override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
        val bmp = BitmapFactory.decodeResource(Resources.getSystem(), resId)
        Log.d(TAG, "loadData ${bmp.byteCount}")
        callback.onDataReady(ByteArrayInputStream(bitmapToByteArray(bmp)))
    }

    override fun cleanup() {
        Log.d(TAG, "cleanup")
    }

    override fun cancel() {
        Log.d(TAG, "cancel")
    }

    override fun getDataClass(): Class<InputStream> {
        return InputStream::class.java
    }

    override fun getDataSource(): DataSource {
        return DataSource.LOCAL
    }


    private fun bitmapToByteArray(bitmap: Bitmap): ByteArray {
        val bos = ByteArrayOutputStream()
        bitmap.compress(CompressFormat.PNG, 0, bos)
        return bos.toByteArray()
    }
}
Kotlin 复制代码
import android.util.Log
import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoaderFactory
import com.bumptech.glide.load.model.MultiModelLoaderFactory
import java.io.InputStream

class VideoCoverLoaderFactory : ModelLoaderFactory<VideoCover, InputStream> {
    val TAG = "Glide/VideoCoverLoaderFactory"

    override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<VideoCover, InputStream> {
        return VideoCoverModuleLoader()
    }

    override fun teardown() {
        Log.d(TAG, "teardown")
    }
}
Kotlin 复制代码
import android.util.Log
import com.bumptech.glide.load.Options
import com.bumptech.glide.load.model.ModelLoader
import com.bumptech.glide.load.model.ModelLoader.LoadData
import com.bumptech.glide.signature.ObjectKey
import java.io.InputStream

class VideoCoverModuleLoader : ModelLoader<VideoCover, InputStream> {
    val TAG = "Glide/VideoCoverModuleLoader"

    override fun buildLoadData(
        model: VideoCover,
        width: Int,
        height: Int,
        options: Options
    ): ModelLoader.LoadData<InputStream>? {
        Log.d(TAG, "buildLoadData")
        return LoadData(
            VideoCoverSignature(model.path!!), //简单时候可以考虑ObjectKey(model.path!!)
            VideoCoverFetcher(model)
        )
    }

    override fun handles(model: VideoCover): Boolean {
        return true
    }
}
Kotlin 复制代码
import com.bumptech.glide.load.Key
import java.security.MessageDigest

class VideoCoverSignature() : Key {
    private var path: String? = null

    constructor(path: String) : this() {
        this.path = path
    }

    override fun updateDiskCacheKey(messageDigest: MessageDigest) {
        val ba: ByteArray = path?.toByteArray()!!
        messageDigest.update(ba, 0, ba.size)
    }
}
Kotlin 复制代码
import android.graphics.drawable.Drawable
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ImageView
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.signature.ObjectKey

class MainActivity : AppCompatActivity() {
    val TAG = "Glide/MainActivity"
    private var image: ImageView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val path = "xxx"

        image = findViewById<ImageView>(R.id.image)
        GlideApp.with(this)
            .load(VideoCover(path))
            .diskCacheStrategy(DiskCacheStrategy.RESOURCE)
            //.signature(ObjectKey(path))
            .addListener(object : RequestListener<Drawable> {
                override fun onLoadFailed(
                    e: GlideException?,
                    model: Any?,
                    target: Target<Drawable>,
                    isFirstResource: Boolean
                ): Boolean {
                    Log.d(TAG, "onLoadFailed")
                    return false
                }

                override fun onResourceReady(
                    resource: Drawable,
                    model: Any,
                    target: Target<Drawable>?,
                    dataSource: DataSource,
                    isFirstResource: Boolean
                ): Boolean {
                    Log.d(TAG, "onResourceReady")
                    return false
                }
            })
            .override(500)
            .into(image!!)
    }
}

Android Glide自定义AppGlideModule,让Glide在app启动后基于定制化GlideModule加载,kotlin_glideapp-CSDN博客在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬而未决:比如用户的头像,往往用户的头像是从服务器端读出的一个普通矩形图片,但是现在的设计一般要求在APP端的用户头像显示成圆形头像,那么此时虽然Glide可以加载,但加载出来的是一个矩形,如果要Glide_android 毛玻璃圆角。《Android图片加载与缓存开源框架:Android Glide》Android Glide是一个开源的图片加载和缓存处理的第三方框架。_glideapphttps://blog.csdn.net/zhangphil/article/details/131592226

Android Glide preload CustomTarget bitmap into LruBitmapPool,kotlin-CSDN博客【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然Glide解决了快速加载图片的问题,但还有一个问题悬而未决:比如用户的头像,往往用户的头像是从服务器端读出的一个普通矩形图片,但是现在的设计一般要求在APP端的用户头像显示成圆形头像,那么此时虽然Glide可以加载,但加载出来的是一个矩形,如果要Glide_android 毛玻璃圆角。《Android图片加载与缓存开源框架:Android Glide》Android Glide是一个开源的图片加载和缓存处理的第三方框架。https://blog.csdn.net/zhangphil/article/details/131667687

相关推荐
Flynt9 分钟前
Room 3.0 包名重构 + KMP 迁移:我把项目升级踩了个遍
android·数据库·kotlin
杉氧29 分钟前
性能优化实战:如何定位冗余重组并榨干 Compose 的每一帧性能?
android·架构·android jetpack
alexhilton12 小时前
将应用迁移到Navigation 3:痛点、加班和紧急修复
android·kotlin·android jetpack
杉氧17 小时前
Navigation Compose 深度实践:如何优雅地串联起你的全栈 App?
android·架构·android jetpack
唐青枫20 小时前
Kotlin 运算符重载详解:为什么 a += b 有时改对象,有时换对象?
kotlin
雨白21 小时前
指针与数组的核心机制
android
黄林晴1 天前
Room 3.0 正式发布!包名彻底重构,KMP 成为核心主线
android·android jetpack
三少爷的鞋1 天前
Kotlin 协程环境下的 DCL 懒加载:别把线程时代的经验直接搬过来
android
plainGeekDev1 天前
Gson → kotlinx.serialization
android·java·kotlin