场景1 Static变量存储上下文环境Context
public class ClassName {// 定义1个静态变量private static Context mContext;//...
// 引用的是Activity的contextmContext = context; // 当Activity需销毁时,由于mContext = 静态 & 生命周期 = 应用程序的生命周期,故 Activity无法被回收,从而出现内存泄露}
结论:
被static修饰的变量生命周期==应用的生命周期,所以当前的mContext变量一旦赋值了activity的上下文环境,就会导致在activity需要销毁时,发现还有强引用mContext在持有该activity,所以无法正常回收掉该activity
解决方案
被static修饰的Context在赋值的时候可以把Application的Context赋值给mContext,这时就不会出现内存泄漏。因为应用的上下文和mContext引用的上下文生命周期一致。
场景2 单例模式
public class SingleInstance {private static SingleInstance instance;private Context mContext;private SingleInstance(Context context) {this.mContext = context;}public static SingleInstance getInstance(Context context){if (instance == null){instance = new SingleInstance(context);}return instance;}
}
结论:
上述代码会存在内存泄漏
原因:
instance对象被static修饰后,该变量的生命周期=应用生命周期,导致该实例所持有的成员变量mContext无法被释放,如果用户传递的Context为Activity的上下文环境,就会导致该activity需要销毁的时候,发现自己的上下文环境还在被这个单例类持有并且设置了强引用,所以无法正常释放并销毁。从而导致内存泄漏
解决方案:
在构造器中通过上下文环境获取应用的上下文环境,赋值给自己的成员变量 mContext,这样该类中的上下文环境的生命周期就和应用的生命周期相等,从而不会出现内存泄漏的情况
private SingleInstance(Context context) {this.mContext = context.getApplicationContext();}