我有点陷入两难境地,我希望你们可以帮助我。
正如您所看到的,我有一个AsyncTask
我在其中有一些代码将Bitmap
个对象保存为.jpg文件到库中。在AsyncTask
我也使用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;
}
}
答案 0 :(得分:3)
由于View
对象明确引用Context
,这是在查看通货膨胀后使用的,因此您实际上是在保持&#34;传递性&#34;通过对Context
进行严格引用,在ViewToBitmap
的实例中对View
进行硬性引用。
此外,由于AsyncSaveBitmap
不是static
,因此此类的实例隐含了对ViewToBitmap
的封闭实例的引用。
最终结果是,只要AsyncSaveBitmap
存在,就会有一系列对Activity
的硬引用会阻止GC Activity
。
所以,答案是:两种方法都不够好。
最好的方法是重构逻辑,使得长时间运行的代码不会引用Context
,Activity
,View
等。
实现这一目标最直接的方法是使用Observer设计模式或Publish-Subscribe设计模式 - 这样你可以&#34;取消注册&#34;在生命周期方法中(例如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();
}