Handler详解(完结)

一,Handler源码分析

Android异步消息处理机制完全解析,带你从源码的角度彻底理解(郭霖)

Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系(鸿洋)

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就不会长期持有外部类的对象。这样可以不做任何处理。如实例二的代码。

你可能感兴趣的:(Handler详解(完结))