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

oxosxuxt  于 2024-01-04  发布在  Android
关注(0)|答案(1)|浏览(309)

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

  1. @GlideModule
  2. public class MyGlideModule extends AppGlideModule {
  3. @Override
  4. public void registerComponents(Context context, Glide glide, Registry registry) {
  5. // Register FirebaseImageLoader to handle StorageReference
  6. registry.append(StorageReference.class, InputStream.class,
  7. new FirebaseImageLoader.Factory());
  8. }
  9. }

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

  1. GlideApp.with(this /* context */)
  2. .load(storageReference)
  3. .diskCacheStrategy(DiskCacheStrategy.NONE)
  4. .skipMemoryCache(true)
  5. .fitCenter()
  6. .error(R.drawable.broken)
  7. .transition(DrawableTransitionOptions.withCrossFade(2000))
  8. .listener(new RequestListener<Drawable>() {
  9. @Override
  10. public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
  11. Log.i("Info","Load failed");
  12. return false;
  13. }
  14. @Override
  15. public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
  16. Log.i("Info","Load successful");
  17. return false;
  18. }
  19. })
  20. .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)检索它。
如果你使用的是协程,我的建议如下:

  1. suspendCoroutine { continuation ->
  2. addListener(
  3. object : RequestListener<T> {
  4. override fun onLoadFailed(
  5. ex: GlideException?,
  6. model: Any?,
  7. target: Target<T>?,
  8. isFirstResource: Boolean
  9. ): Boolean {
  10. continuation.resumeWithException(ex ?: RuntimeException())
  11. return false
  12. }
  13. override fun onResourceReady(
  14. resource: T,
  15. model: Any?,
  16. target: Target<T>?,
  17. dataSource: DataSource?,
  18. isFirstResource: Boolean
  19. ): Boolean {
  20. continuation.resume(resource)
  21. return false
  22. }
  23. }
  24. ).submit().get(timeoutMs, TimeUnit.MILLISECONDS)
  25. }

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

  1. // ...
  2. ): ModelLoader.LoadData<InputStream> {
  3. val timeout = options.get(HttpGlideUrlLoader.TIMEOUT) ?: 2_500
  4. return ModelLoader.LoadData(
  5. FirebaseStorageKey(ref),
  6. FirebaseStorageFetcher(ref, timeout)
  7. )
  8. }
  9. // ...


FirebaseFetcher

  1. // ...
  2. override fun loadData(priority: Priority, callback: DataFetcher.DataCallback<in InputStream>) {
  3. try {
  4. stream = Tasks
  5. .await(ref.stream.also { this.task = it }, timeout.toLong(), TimeUnit.MILLISECONDS)
  6. .stream
  7. callback.onDataReady(stream)
  8. } catch (ex: Exception) {
  9. callback.onLoadFailed(ex)
  10. }
  11. }
  12. // ...


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

展开查看全部

相关问题