问题
在Android开发中,经常会将工具类以单例模式的方法实现,而工具类中又总不可避免的用到 Context
,例如:
public class MySingleton {
private static volatile MySingleton instance;
private final Context ctx;
private MySingleton(Context context) {
ctx = context;
}
public static MySingleton getInstance(Context context) {
if (instance == null) {
synchronized (MySingleton.class) {
if (instance == null) {
instance = new MySingleton(context);
}
}
}
return instance;
}
}
那么就会出现:
Warning: Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)
包括 Google 自己的单例模式使用举例都会有这个错误……
解决方法
这是因为普通 Activity
的 Context
的生命周期未必有 final Context ctx
(实际上是static MySingleton
) 长,因此有内存泄漏的风险。
查阅了大量资料后,解决方法主要参考这里,最终的代码实现如下:
public class MySingleton {
private static volatile MySingleton instance;
private final Context ctx;
private MySingleton(Context context) {
// 调用 getApplicationContext()
// 返回当前进程的单个全局应用程序对象的上下文。
// 这意味着 getApplicationContext() 返回的上下文将贯穿整个程序
ctx = context.getApplicationContext();
}
public static MySingleton getInstance(Context context) {
if (instance == null) {
synchronized (MySingleton.class) {
if (instance == null) {
instance = new MySingleton(context);
}
}
}
return instance;
}
}