緣由: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,以便取消產生的引用