我应该在AsyncTask中使用WeakReference <Context>或Application Context吗?

5 android

我有点陷入两难境地,我希望你们可以帮助我.

正如你所看到的AsyncTask,我有一些代码可以将Bitmap对象作为.jpg文件保存到库中.在AsyncTask我也使用a Context,但据我所知使用Activity此内部类的上下文可能会导致内存泄漏,所以我将其更改为一个WeakReference<Context> weakContext;垃圾收集器可以收集它.

但是通过使用Application我从View构造函数传递的上下文,我应该归档与弱上下文引用相同的效果

那么在这种情况下使用比其他更好吗?

public class ViewToBitmap {

private View view;
private WeakReference<Context> weakContext;

public ViewToBitmap(@NonNull View view) {
    this.view = view;
}

 // This?
private WeakReference<Context> getContext() {
    weakContext = new WeakReference<>(view.getContext());
    return weakContext;
}

 // Or This?
private Context getContext() {
    return view.getContext().getApplicationContext();
}

private class AsyncSaveBitmap 
                extends AsyncTask<Void, Void, Void> 
                implements MediaScannerConnection.OnScanCompletedListener {

    @Override
    protected Void doInBackground(Void... params) {
      //TODO: Save bitmaps to gallery
      //CONTEXT IS USED HERE
       getContext().get()
       return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

Vas*_*liy 4

由于该对象具有对视图膨胀时使用的View显式引用,因此通过保留对 的硬引用,您可以有效地在 的实例中保留对 的“传递”硬引用。ContextContextViewToBitmapView

此外,由于AsyncSaveBitmap不是static,因此此类的实例具有对封闭实例的隐式引用ViewToBitmap

最终结果是,只要AsyncSaveBitmap存在,就会存在一系列硬引用,Activity这将阻止 GC 的发生Activity

所以,答案是:这两种方法都不够好。

最好的方法是以这样的方式重构逻辑,使得长时间运行的代码不会引用ContextActivityView等。

实现这一点的最直接的方法是使用观察者设计模式或发布订阅设计模式 - 这样您可以在生命周期方法(例如onStop())中“取消注册”,从而消除潜在危险的引用并防止内存泄漏。

编辑:

出于库的目的,您不一定需要特定的Context应用程序Context就足够了,可以使用以下模式(取决于您的库是否公开为单例):

// Use this approach if clients will use your library as Singleton
private static Context sAppContext;

public static void init(Context context) {
    sAppContext = context.getApplicationContext();
}

// Use this approach if clients will instantiate your library's object on each use
private final Context mAppContext;

public MyLibraryEntryClass(Context context) {
    mAppContext = context.getApplicationContext();
}
Run Code Online (Sandbox Code Playgroud)