2、使用匿名内部类的时候经常出现的错误
错误方式:
public class FooActivity extends Activity{
private TextView textView;
private Handler handler = new Handler(){
@override
public void handlerMessage(Message msg){
}
};
@override
public void onCreate(Bundle bundle){
super.onCreate(bundle);
setContextView(R.layout.activity_foo_layout);
textView = (TextView)findViewById(R.id.textView);
handler.postDelayed(new Runnable(){
@override
public void run(){
textView.setText(“ok”);
};
},1000 * 60 * 10);
}
}
错误原因:
当我们执行了FooActivity的finish方法,被延迟的消息会在被处理之前存在于主线程消息队列中10分钟,而这个消息中又包含了Handler的引用,而Handler是一个匿名内部类的实例,其持有外面的FooActivity的引用,所以这导致了FooActivity无法回收,进而导致FooActivity持有的很多资源都无法回收,所以产生了内存泄露。
注意上面的new Runnable这里也是匿名内部类实现的,同样也会持有FooActivity的引用,也会阻止FooActivity被回收。
一个静态的匿名内部类实例不会持有外部类的引用。
正确方式:
public class FooActivity extends Activity{
private TextView textView;
private static class MyHandler extends Handler {
private final WeakReference<FooActivity> mActivity;
public MyHandler(FooActivity activity) {
mActivity = new WeakReference<FooActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
FooActivity activity = mActivity.get();
if (activity != null) {
// ...
}
}
}
private final MyHandler handler = new MyHandler(this);
@override
public void onCreate(Bundle bundle){
super.onCreate(bundle);
setContextView(R.layout.activity_foo_layout);
textView = (TextView)findViewById(R.id.textView);
handler.postDelayed(new MyRunnable(textView),1000 * 60 * 10);
}
private static class MyRunnable implements Runnable{
private WeakReference<TextView> textViewWeakReference;
public MyRunnable(TextView textView){
textViewWeakReference = new WeakReference<TextView>(textView);
}
@override
public void run(){
final TextView textView = textViewWeakReference.get();
if(textView != null){
textView.setText("OK");
}
};
}
}










