使用应用程序上下文滑动图像加载

Glide image loading with application context

我在我的 android 应用程序中使用 glide 进行图像加载,以避免任何崩溃,我正在使用应用程序上下文加载图像。这对应用程序和内存的性能有何影响?

What will be effect of this on performance of application and memory?

Glide 提供这么多 .with() 方法是有原因的:它遵循生命周期。

想象一个动态添加到 Activity 的 Fragment。在其 onCreateView 方法中,它开始 Glide 加载 3MB 图像。现在,如果用户按下后退按钮并且 Fragment 被删除或整个 activity 关闭怎么办?

  • 如果你使用 with(getActivity().getApplicationContext()) 什么都不会发生,所有 3MB 的数据都被下载然后解码,缓存,甚至可能设置到 ImageView,然后被垃圾收集,因为对它的唯一引用来自滑翔内部。
  • 如果你使用 with((Fragment)this) Glide 订阅了 Fragment 的生命周期事件,一旦 Fragment 停止,任何未完成的请求都应该暂停;当销毁时,所有未决请求将被清除。这意味着图像下载将中途停止,并且该死片段将不再使用资源。
  • 如果你使用 with(getActivity()) Glide 订阅了 Activity 的生命周期事件并且发生了与上面相同的事情,但只有当 Activity 被停止或销毁时才会发生。

所以最好的做法是使用尽可能接近的 context/fragment 来避免未使用的请求完成! (还有一种手动停止加载的方法:Glide.clear(ImageView|Target)。)


要在实践中应用它,请尽可能使用 with(this),但如果不是,例如在适配器或集中式图像加载方法中,传入一个 RequestManager glide 作为参数,并且使用 glide.load(...,例如:

static loadImage(RequestManager glide, String url, ImageView view) {
    glide.load(url).into(view);
}

或在适配器中:

class MyAdapter extends WhichEveryOneYouUse {
    private final RequestManager glide;
    MyAdapter(RequestManager glide, ...) {
        this.glide = glide;
        ...
    }
    void getView/onBindViewHolder(... int position) {
        // ... holder magic, and get current item for position
        glide.load... or even loadImage(glide, item.url, holder.image);
    }
}

并使用来自 Activity/Fragment 的这些:

loadImage(Glide.with(this), url, findViewById(R.id.image));
// or
list.setAdapter(new MyAdapter(Glide.with(this), data));

将 Glide 请求与所有者的生命周期同步的通用解决方案。可以从任何地方调用:Activity、片段、RV 适配器、自定义视图等

private fun RequestManager.syncWithLifecycleOwner(view: View): RequestManager {

val syncRequest = object : DefaultLifecycleObserver {
    override fun onStart(owner: LifecycleOwner) = onStart()
    override fun onStop(owner: LifecycleOwner) = onStop()
    override fun onDestroy(owner: LifecycleOwner) {
        onDestroy()
        owner.lifecycle.removeObserver(this)
    }
}

view.findViewTreeLifecycleOwner()?.lifecycle?.addObserver(syncRequest)

return this

}

然后您可以像这样创建一个简单的扩展函数:

fun ImageView.loadUrl(url: String) {
   Glide
      .with(context.applicationContext)
      .syncWithLifecycleOwner(this)
      .load(url)
      .into(this) 
}

findViewTreeLifecycleOwner() 存在于 AndroidX 生命周期库中。它提供了 Activity 或片段视图的生命周期 (viewLifecycleOwner) 这个特定的 ImageView 附加到。您将需要从视图中传递应用程序上下文,以确保 Glide 库不会调用回调本身。