android 使用Glide从Firebase下载图像-如何实现超时?

oxosxuxt  于 4个月前  发布在  Android
关注(0)|答案(1)|浏览(87)

我成功地使用Glide从Firebase下载图像。
我有我的标准GlideModule:

@GlideModule
public class MyGlideModule extends AppGlideModule {

    @Override
    public void registerComponents(Context context, Glide glide, Registry registry) {
        // Register FirebaseImageLoader to handle StorageReference
        registry.append(StorageReference.class, InputStream.class,
                new FirebaseImageLoader.Factory());
    }
}

字符串
然后在我的活动中:

GlideApp.with(this /* context */)
        .load(storageReference)
        .diskCacheStrategy(DiskCacheStrategy.NONE)
        .skipMemoryCache(true)
        .fitCenter()
        .error(R.drawable.broken)
        .transition(DrawableTransitionOptions.withCrossFade(2000))
        .listener(new RequestListener<Drawable>() {
            @Override
            public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
                Log.i("Info","Load failed");
                return false;
            }

            @Override
            public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
                Log.i("Info","Load successful");
                return false;
            }
        })
        .into(imageView);


这通常工作正常,但当设备没有互联网连接时,imageview保持空白-不会触发R.drawable.broken错误图像,也不会触发onLoadFailedonResourceReady。如果信号恢复,则图像会出现。
我想检测到这种情况的发生,并向用户发出他们需要更好信号的标志。(好像没有)。然而,简单地将.timeout(3000)添加到Activity部分并不起作用,因为在使用GlideModule时会忽略此操作。我假设答案位于FirebaseImageLoader.Factory()的设置中的某个位置,但我找不到任何文档,从源代码中看不清楚。

41ik7eoe

41ik7eoe1#

我来到这里,因为我遇到了同样的要求,所以我很高兴分享我的想法后,我的研究。
FirebaseImageLoaderGlide的builder中设置时不支持超时选项。您需要创建自己的自定义加载器或使用现有的超时值来解决问题。
应该注意的是,可以默认设置为Glide的超时旨在用于网络超时。
Glide的超时存储在一个以HttpGlideUrlLoader.TIMEOUT为键的选项中,您可以通过RequestBuilder.getOptions().get(HttpGlideUrlLoader.TIMEOUT)检索它。
如果你使用的是协程,我的建议如下:

suspendCoroutine { continuation ->
    addListener(
        object : RequestListener<T> {
            override fun onLoadFailed(
                ex: GlideException?,
                model: Any?,
                target: Target<T>?,
                isFirstResource: Boolean
            ): Boolean {
                continuation.resumeWithException(ex ?: RuntimeException())
                return false
            }

            override fun onResourceReady(
                resource: T,
                model: Any?,
                target: Target<T>?,
                dataSource: DataSource?,
                isFirstResource: Boolean
            ): Boolean {
                continuation.resume(resource)
                return false
            }
        }
    ).submit().get(timeoutMs, TimeUnit.MILLISECONDS)
}

字符串
在自定义加载器的情况下,您可以使用现有的FirebaseImageLoader源代码作为基础并进行一些修改。加载器知道Glide的选项,因此您可以从中获取超时并传递到fetch,它负责从Firebase Storage获取数据并进行自己的自定义处理,例如。
FirebaseImageLoader

// ...
    ): ModelLoader.LoadData<InputStream> {
        val timeout = options.get(HttpGlideUrlLoader.TIMEOUT) ?: 2_500
        return ModelLoader.LoadData(
            FirebaseStorageKey(ref),
            FirebaseStorageFetcher(ref, timeout)
        )
    }
// ...


FirebaseFetcher

// ...
    override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
        try {
            stream = Tasks
                .await(ref.stream.also { this.task = it }, timeout.toLong(), TimeUnit.MILLISECONDS)
                .stream
            callback.onDataReady(stream)
        } catch (ex: Exception) {
            callback.onLoadFailed(ex)
        }
    }
// ...


最后,将您自己的类注册到GlideModule

相关问题