一、Handler 内存泄露的原因
参考:http://m.myexception.cn/android/2108819.html
1.内部类的方式实例化Handler
Handlerhandler=newHandler(){
@Override
publicvoidhandleMessage(Messagemsg){
super.handleMessage(msg);
}
};
这个的问题是 Java 中 成员内部类及匿名内部类都会隐式的持有外部类对象的引用,影响外部类对象的回收。GC只会回收没有被引用或者根集不可到达的对象(取决于GC算法),内部类在生命周期内始终持有外部类的对象的引用,造成外部类的对象始终不满足GC的回收条件,反映在内存上就是内存泄露。
2.生命周期和 Activity 不一样
内部类持有外部类Activity的引用,当Handler对象有Message在排队,则无法释放,进而导致Activity对象不能释放。
正确 Handler 的写法:
MyHandlermhandler;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
mhandler=newMyHandler(this);
mhandler.sendEmptyMessage(0);
}
staticclassMyHandlerextendsHandler{
privateWeakReferenceactivityWeakReference;
publicMyHandler(MainActivityactivity){
activityWeakReference=newWeakReference(activity);
}
@Override
publicvoidhandleMessage(Messagemsg){
super.handleMessage(msg);
MainActivityact=activityWeakReference.get();
if(activityWeakReference!=null&&act!=null){
// ......
}}}
Handler 回收方式
方式一
mhandler.removeMessages(0);
mhandler.removeMessages(1);
mhandler.removeMessages(2);
mhandler.removeCallbacks(r);
方式二
@Override
protectedvoidonDestroy(){
super.onDestroy();
mhandler.removeCallbacksAndMessages(null);
}
回收方式二官方说明
Removeany pending posts of callbacksandsent messages whose objistoken.Iftokenisnull,all callbacksandmessages will be removed
大概意思是: 意思就是当传入的参数为null时,则移除所有的callbacks和messages,这样就有效的避免了由Handler引起的内存溢出。
网友评论