缘由:java
Handler.handlerMessage(Message)
来处理消息public class SampleActivity extends Activity {
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
//...
}
}
}
复制代码
解决办法:git
将Handler设置为静态内部类(具体参考静态内部类和内部类区别),并使使Handler持有对Activity的弱引用github
public class SampleActivity extends Activity {
.......
private static class MyHandler extends Handler {
private final WeakReference<SampleActivity> mActivity;
public MyHandler(SampleActivity activity) {
myActivity = new WeakReference<SampleActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
SampleActivity activity = mActivity.get();
if (activity != null) {
...
}
}
}
}
复制代码
在activity生命周期onDestroy()
中调用Handler.removeCallback()
方法bash
// 清空消息队列,移除对外部类的引用
@Override
protected void onDestroy() {
super.onDestroy();
mHandler.removeCallbacksAndMessages(null);
}
//Handler源码中removeCallbacksAndMessages()注释含义
/**
* Remove any pending posts of callbacks and sent messages whose
* <var>obj</var> is <var>token</var>. If <var>token</var> is null,
* all callbacks and messages will be removed.
*/
public final void removeCallbacksAndMessages(Object token) {
mQueue.removeCallbacksAndMessages(this, token);
}
复制代码
复制代码
内部类的优点:ide
内部类方法能够访问盖内定义所在做用域的数据,包括私有数据函数
内部类能够对同一个包中其余类隐藏oop
想定义一个回调函数并且不像编写大量代码时,使用匿名内部类比较简洁post
原理:this
内部类的对象总有一个隐式引用,它指向了建立它的外部类对象spa
编译器修改了全部内部类的构造器,添加了一个外围类的引用参数:
public class Outer {
...
class Inner {
...
//Outer为外部类,Inner为内部类
Outer out;
public Inner(Outer outer) {
out = outer;
}
}
}
复制代码
静态内部类: 使用内部类只是为了把一个类隐藏在另外一个类的内部,并不须要内部类引用外围类的对象。 所以能够将内部类声明为static,以便取消产生的引用