Android自定义Handler使用静态内部类避免内存泄漏
在Activity中声明Handler类时,Android Studio会提示警告:
This Handler class should be static or leaks might occur
例如这样的代码:
public class MainActivity extends Activity {
// This Handler class should be static or leaks might occur
class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) { }
}
}
因为如果Handler使用UI线程来做消息序列的处理,那么可能会导致Activity类无法被回收,继而引发内存泄漏。
通俗的讲,耗时内部类引用外部类,可能导致外部类无法回收
因此按照警告中的提示,Handler应声明为静态内部类:
public class MainActivity extends Activity {
static class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) { }
}
}
声明为静态类以后,Handler就没有了Activity的引用,无法直接引用其变量或方法了,因此我们在这里使用弱引用WeakReference来解决这个问题:
static class MyHandler extends Handler {
WeakReference<MainActivity> activity;
public DownloadHandler(MainActivity mainActivity) {
activity = new WeakReference<MainActivity>(mainActivity);
}
@Override
public void handleMessage(Message msg) { }
}
WeakReference可以尽早地被GC回收掉,因此可以防止内存泄漏。由于这里的activity变量实际不是MainActivity类型的,因此在handleMessage中还要多一步获取与判断:
@Override
public void handleMessage(Message msg) {
if (activity.get() != null) {
activity.get().someMethod();
}
}
当然每次这样调用比较麻烦,可以将WeakReference声明初始化在MainActivity中,在Handler初始化时直接传入:
public class MainActivity extends Activity {
WeakReference<MainActivity> activity;
MyHandler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
activity = new WeakReference<MainActivity>(mainActivity);
mHandler = new MyHandler(activity);
}
class MyHandler extends Handler {
private MainActivity activity;
public MyHandler(WeakReference<MainActivity> ref) {
activity = ref.get();
}
@Override
public void handleMessage(Message msg) {
if(activity != null) {
activity.someMethod();
}
}
}
}
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/02/25/android-custom-handler-use-static-inner-class-to-avoid-memory-leak/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论