內(nèi)存泄漏的幾種情況
1.使用了非靜態(tài)匿名內(nèi)部類對象(如handler、線程)
在Activity中直接使用new handler();因?yàn)榉庆o態(tài)內(nèi)部類會隱式持有外部類實(shí)例,導(dǎo)致activity不能回收;
解決方法:
使用靜態(tài)的handler
private static class MyHandler extends Handler {
private WeakReference<Context> reference;
public MyHandler(Context context) {
reference = new WeakReference<>(context);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = (MainActivity) reference.get();
if (activity != null) {
activity.mTextView.setText("");
}
}
}
WeakReference<Activity> weakActivity;
weakActivity =new WeakReference<Activity>(activity);
Activity activity = weakActivity.get();
if(activity !=null){
// do your stuff with activity here}
}
或者可以:
public abstract class MyHandler<T extends Context> extends Handler {
private WeakReference<T> reference;
public MyHandler(T context) {
reference = new WeakReference<>(context);
}
@Override
public void handleMessage(Message msg) {
T activity = reference.get();
if (activity != null) {
handleMessage(activity, msg);
}
}
public abstract void handleMessage(T activity, Message msg);
}
線程:
也是一樣使用靜態(tài)內(nèi)部類;
2.單例持有了有生命周期的對象的引用
解決方法:單例的生命周期和應(yīng)用一樣長,所以持有了短生命周期的對象(如Activity)會導(dǎo)致該對象無法回收。可以使用ApplicationContext,或者弱引用。關(guān)于使用的場合可以參考difference-between-activity-context-and-application-context
3.資源打開用完了未關(guān)閉
如cursor,bitmap,BraodcastReceiver等,解決方法就是記得關(guān)閉和注銷;一些庫用到了注冊也要解注冊。