可以在helper类中使用context导致android中的内存泄漏
我有一个带有以下方法的辅助类
public class HelperClass {
private Context context;
public HelperClass(Context context) {
this.context = context;
}
public void Addfiles(Context context, String Filename) {
try {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(Filename);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
context.sendBroadcast(mediaScanIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
在我的MainActivity中,我想像这样称呼它
public class MyActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
HelperClass h = new HelperClass(this);
h.Addfiles(this,Filename);
}
}
我想知道可以使用像这样的上下文导致内存泄漏,如果是这样,如何处理它。
答案 0 :(得分:1)
TL; DR - 严格地说是上面的情况,不,因为在“onCreate”中MyActivity不会被销毁
答案很长:
通常,当垃圾收集器运行时,当某个对象无法进行垃圾回收时会发生内存泄漏,因为某些对象仍然引用它。
在您的情况下,刚刚创建活动,主要关注的是泄漏是否可能发生,因为HelperClass
包含对它的引用。
首先,在正常情况下(除了AOS可能会杀死你的应用程序)MainActivity
保证在调用onDestroy
方法之前不会收集垃圾。这是因为在那之前(并且可能在那之后的一段时间 - 不相关)它将被Android框架本身引用。
HelperClass
是onCreate
内的局部变量。完成onCreate
后,HelperClass
可能会在任何时候被垃圾收集,因为它没有引用它的任何对象(请参阅here)。因此HelperClass
之前调用onDestroy
的机会非常高。如果发生这种情况,则不会引用MainActivity
- >没有泄漏。
如果在HelperClass
上调用onDestroy
之前不会对MainActivity
进行垃圾回收,则事件仍然没有泄漏,因为垃圾收集器足够智能以便能够清理循环引用。
发生泄密需要发生的事情是,一个超过Activity
的对象将保留对它的引用或其上下文。
假设你的代码是这样的:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final HelperClass h = new HelperClass(this);
//does some work on a background thread, gets notified at some
//point in the future, through the callback, when the work
//has completed
longLivedComponent.doSomeBackgroundWork(new OnWorkFinishedListener(){
@Override
public void onWorkFinished(){
h.Addfiles(this, filename);
}
});
}
现在,让我们假设以下事件序列:
MainActivity
#1已创建,其onCreate
被称为doSomeBackgroundWork
,开始后台工作。当后台工作完成后,你的助手(引用MainActivity
#1)将不得不做一些工作。MainActivity
由Android重新创建。 MainActivity
#1已被销毁(即onDestroy
将被调用),并且将创建新的MainActivity
#2 MainActivity
#2将发生第1,2步,即doSomeBackgroundWork
#2将再次调用MainActivity
。 (严格来说,这一步并不是真正相关,但仍然如此)MainActivity
#1在步骤#2 开始的后台工作完成。通常,在步骤#6 时,MainActivity
#1占用的内存将被释放,因为MainActivity
#1已被销毁。
但是,在此处描述的情况下,OnWorkFinishedListener
需要longLivedComponent
保留,直到后台工作完成。监听器既可以引用MainActivity
#1(对其父类的隐式匿名内部类引用),也可以引用HelperClass
实例,该实例还包含MainActivity
#1的实例
当垃圾收集器在步骤#6 看到此情况时,它会认为MainActivity
#1仍处于活动状态&因为stil是指向它的对象。因此,它不会回收它的内存,你最终会在内存中出现MainActivity
的两个实例并发生泄漏。
为了防止这种情况,你可以:
Activity
或其Context
的引用已经被称为onDestroy()
希望这有帮助