美文网首页
android glide仅wifi下下载

android glide仅wifi下下载

作者: yin_xin | 来源:发表于2021-03-17 18:42 被阅读0次

一个旧项目需要添加仅wifi下加载图片的配置功能,因为该项目并没有封装图片加载,只是直接使用了glide加载图片,常规改造方法工作量巨大,于是有了这篇。


实现思路是通过自定义的Loader,实现wifi下正常逻辑,非wifi下跳过下载流程。
官方文档,https://muyangmin.github.io/glide-docs-cn/tut/custom-modelloader.html

自定义Fetcher

这个类是图片下载的核心逻辑。

class NewsFetcher(private val client: Call.Factory, private val url: GlideUrl) :
    DataFetcher<InputStream>, okhttp3.Callback {

    private val TAG = NewsFetcher::class.java.name

    @Volatile
    private var call: Call? = null
    private var callback: DataFetcher.DataCallback<in InputStream>? = null
    private var stream: InputStream? = null
    private var responseBody: ResponseBody? = null


    override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
        if (不满足下载图片的情况) {
            return
        }
        //使用okhttp 请求图片
        val requestBuilder = Request.Builder().url(url.toStringUrl())
        for ((key, value) in url.headers) {
            requestBuilder.addHeader(key, value)
        }
        val request = requestBuilder.build()
        this.callback = callback
        call = client.newCall(request)
        call?.enqueue(this)
    }

    override fun cleanup() {
        try {
            stream?.close()
        } catch (e: IOException) {
            // Ignored
        }
        responseBody?.close()
        callback = null
    }

    override fun cancel() {
        val local = call
        local?.cancel()
    }

    override fun getDataClass(): Class<InputStream> = InputStream::class.java

    override fun getDataSource(): DataSource = DataSource.REMOTE

    override fun onFailure(call: Call, e: IOException) {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "OkHttp failed to obtain result", e)
        }
        callback?.onLoadFailed(e)

    }

    override fun onResponse(call: Call, response: Response) {
        responseBody = response.body()
        if (response.isSuccessful) {
            val contentLength =
                Preconditions.checkNotNull(responseBody).contentLength()
            stream = ContentLengthInputStream.obtain(responseBody!!.byteStream(), contentLength)
            callback?.onDataReady(stream)
        } else {
            callback?.onLoadFailed(HttpException(response.message(), response.code()))
        }

    }
}

ModelLoader

  1. 定义一个okhttp单例
object NewsInternalClient {
    val internalClient: Call.Factory = OkHttpClient()
}
  1. modelLoader
class NewsModelLoader(private val client: Call.Factory) : ModelLoader<GlideUrl, InputStream> {

    override fun handles(url: GlideUrl): Boolean {
        return true
    }

    override fun buildLoadData(
        model: GlideUrl,
        width: Int,
        height: Int,
        options: Options
    ): ModelLoader.LoadData<InputStream>? {
        return ModelLoader.LoadData(model,
            NewsFetcher(client, model)
        )
    }

    class Factory : ModelLoaderFactory<GlideUrl, InputStream> {

        override fun build(multiFactory: MultiModelLoaderFactory): ModelLoader<GlideUrl, InputStream> {
            return NewsModelLoader(NewsInternalClient.internalClient)
        }

        override fun teardown() {
            // Do nothing, this instance doesn't own the client.
        }
    }

}

LibraryGlideModule

因为我的逻辑是在module中,所以使用LibraryGlideModule,如果你的实在app module则使用AppGlideModule。

@GlideModule
class NewsGlideModel : LibraryGlideModule() {

    override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
        registry.replace(
            GlideUrl::class.java, InputStream::class.java,
            NewsModelLoader.Factory()
        )
    }
}

最后

到这里你的配置还不会生效,需要在app module中编写一个空的AppGlideModule

@GlideModule
public class MyAppGlideModel extends AppGlideModule {
}

在使用到glide注解的模块添加处理器
kapt 'com.github.bumptech.glide:compiler:4.11.0'

大功告成,正常使用glide即可。

相关文章

网友评论

      本文标题:android glide仅wifi下下载

      本文链接:https://www.haomeiwen.com/subject/xhvecltx.html