一,Handler源码分析
image.png
二,Handler中影藏的设计思想
1,Handler发送的消息在MessageQueue中为什么要用单链表存储。
Message在应用内中被频繁使用,单链表方便扩容。
2,Message的创建的时候为啥要使用obtain的方式创建Message对象。
Message是一个被频繁使用到的,为了减少内存频繁被分配和销毁从而频繁gc。
三,实战handler内存泄漏
示例一,下面的代码就有可能出现会内存泄漏
public class HandlerActivity extends Activity {
private static String TAG = "HandlerActivity ";
private static int index = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_java);
handler.sendEmptyMessageDelayed(1, 1000);
}
private Handler handler = new Handler() {
@SuppressLint(value = "HandlerLeak")//表示有可能出现内存泄漏
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
index++;
Log.i(TAG, " handlerMessage index = " + index);
handler.sendEmptyMessageDelayed(1, 1000);
}
};
}
原因是HandlerActivity 的内部类持有了HandlerActivity 这个类的对象,当HandlerActivity 被onDestroy后这个时候HandlerActivity 依然会被持有,因此就出现了内存泄漏。
示例二,下面代码就不会出现内存泄漏
public class HandlerActivity extends Activity {
private static String TAG = "HandlerActivity ";
private static int index = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_handler_java);
handler.sendEmptyMessageDelayed(1, 1000);
}
@Override
protected void onDestroy() {
super.onDestroy();
handler.sendEmptyMessage(1);
}
private static Handler handler = new Handler() {
@SuppressLint(value = "HandlerLeak")//表示有可能出现内存泄漏
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
Log.i(TAG, " handlerMessage msg.what= " + msg.what);
}
};
}
解决方法:
1,在Handler创建的时候使用static修饰。当Activity被onDestroy后就会被回收了。因为静态内部类不持有外部类的引用。
2,使用弱引用或者软引用。
3,如果在Activity被onDestroy后不用去发送进行消息发送了就可以在onDestroy方法中添加removeCallBackAndMessages(null)方法。
4,如果在Message中发送结束Handler就被Recycle了,这样Hanler就不会长期持有外部类的对象。这样可以不做任何处理。如实例二的代码。