把Activity作为Context直接传给静态对象,
单例模式不正确的获取context
public class LoginManager {
private Context context;
private static LoginManager manager;
public static LoginManager getInstance(Context context) {
if (manager == null)
manager = new LoginManager(context);
return manager;
}
private LoginManager(Context context) {
this.context = context;
}
在LoginActivity中
public class LoginActivity extends Activity {
private LoginManager loginManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
loginManager = LoginManager.getInstance(this);
}
在LoginManager的单例中context持有了LoginActivity的this对象,即使登录成功后我们跳转到了其他Activity页面,LoginActivity的对象仍然得不到回收因为他被单例所持有,而单例的生命周期是同Application保持一致的。
正确的获取context的方式
public class LoginManager {
private Context context;
private static LoginManager manager;
public static LoginManager getInstance(Context context) {
if (manager == null)
manager = new LoginManager(context);
return manager;
}
private LoginManager(Context context) {
this.context = context.getApplicationContext();
}
修改方式也非常简单我们单例中context不再持有Activity的context而是持有Application的context即可,因为Application本来就是单例,所以这样就不会存在内存泄漏的的现象了。
单例模式中通过内部类持有activity对象
内部类的使用造成activity对象被单例持有。
还是看代码再分析,下面是一个单例的类:
public class TestManager {
public static final TestManager INSTANCE = new TestManager();
private List<MyListener> mListenerList;
private TestManager() {
mListenerList = new ArrayList<MyListener>();
}
public static TestManager getInstance() {
return INSTANCE;
}
public void registerListener(MyListener listener) {
if (!mListenerList.contains(listener)) {
mListenerList.add(listener);
}
}
public void unregisterListener(MyListener listener) {
mListenerList.remove(listener);
}
}
interface MyListener {
public void onSomeThingHappen();
}
然后是activity:
public class TestActivity extends AppCompatActivity {
private MyListener mMyListener=new MyListener() {
@Override
public void onSomeThingHappen() {
}
};
private TestManager testManager=TestManager.getInstance();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
testManager.registerListener(mMyListener);
}
}
我们知道在java中,非静态的内部类的对象都是会持有指向外部类对象的引用的,因此我们将内部类对象mMyListener让单例所持有时,由于mMyListener引用了我们的activity对象,因此造成activity对象也不能被回收了,从而出现内存泄漏现象。
修改以上代码,避免内存泄漏,在activity中添加以下代码:
@Override
protected void onDestroy() {
testManager.unregisterListener(mMyListener);
super.onDestroy();
}