一、了解Android消息机制
Android消息机制是指通过 Message、Handler 和 Looper 三者相互配合,实现在子线程中发送消息、处理消息,从而实现异步执行任务的方案。其中,Message 负责携带消息的内容,Handler 负责处理消息,而 Looper 则是消息循环机制的核心。在此机制下,我们可以在主线程中往子线程中发送消息,也可以在子线程中向主线程发送消息,从而实现更加灵活的多线程编程。
二、学习Looper类的基本结构
public class Looper { private static final Object sLock = new Object(); private static Looper sMainLooper = null; final MessageQueue mQueue; private final Thread mThread; private boolean mRun; private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); } public static void prepare() { prepare(true); } public static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); } public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; for (;;) { Message msg = queue.next(); // might block if (msg == null) { return; } try { msg.target.dispatchMessage(msg); } finally { msg.recycleUnchecked(); } } } public static void quit() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } synchronized (me.mQueue) { me.mRun = false; me.mQueue.notifyAll(); } } public static Looper myLooper() { return sThreadLocal.get(); } }
以上是 Looper 类的源码,其中最重要的属性是 MessageQueue,它通过链表的结构保存所有需要执行的消息。Looper 自身则主要是调用 MessageQueue 的 next 方法进行轮询,然后将消息交给对应的 Handler 处理,最后将 Message 回收利用以节约资源。
三、了解Message的实现
public final class Message { public int what; public int arg1; public int arg2; public Object obj; public long when; public Handler target; Message next; public int sendingUid = -1; public Bundle data; private static final Object sPoolSync = new Object(); private static Message sPool; private static int sPoolSize = 0; private static final int MAX_POOL_SIZE = 50; private static boolean gCheckRecycle = true; private boolean mRecycled; public static final int FLAG_IN_USE = 1 << 0; int flags; private static final int FLAGS_TO_CLEAR_ON_COPY_FROM = FLAG_IN_USE; private static boolean gCheckRecycleUnchecked = true; private Message() {} public static Message obtain(Handler h) { Message m = get(); m.target = h; return m; } private static Message get() { synchronized (sPoolSync) { if (sPool != null) { Message m = sPool; sPool = m.next; m.next = null; m.flags = 0; m.sendingUid = -1; sPoolSize--; return m; } } return new Message(); } void recycleUnchecked() { if (mRecycled) { if (gCheckRecycleUnchecked) { throw new IllegalStateException("This message cannot be recycled because it " + "is still in use."); } return; } mRecycled = true; clearForRecycle(); synchronized (sPoolSync) { if (sPoolSize < MAX_POOL_SIZE) { next = sPool; sPool = this; sPoolSize++; } } } void clearForRecycle() { flags = 0; what = 0; arg1 = 0; arg2 = 0; obj = null; when = 0; target = null; // Explicitly target data to its more specific implementation to ensure // that it's correctly recycled after a transfer. data = null; } }
以上代码是 Message 类的实现代码,它主要包括消息类型和消息内容,配合 Handler 来执行对应的操作。其中 mostPoolSize 规定了该类允许缓存的最大实例数量,可以看到它通过静态 sPoolSync 锁实现了资源的共享,以此达到了 Message 回收、利用和避免浪费的效果。
四、创建一个自定义Handler进行消息处理
public class MyHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); // 根据不同的消息类型,执行对应的操作 switch (msg.what) { case 1: // 执行操作1 break; case 2: // 执行操作2 break; default: break; } } }
通过继承 Handler 类,我们可以在自定义的 handleMessage 方法中处理各种不同消息类型的执行操作。其中,msg.what 用于表示消息类型,可以根据不同的需求来自定义,比如用数字表示不同的操作,或者用 final 常量来表示特定的操作。
五、在子线程中使用 Looper
public class MyThread extends Thread { @Override public void run() { Looper.prepare(); MyHandler handler = new MyHandler(); Looper.loop(); } public void sendMessage(Message msg) { if (handler != null) { handler.sendMessage(msg); } } }
以上代码演示了如何在子线程中使用 Looper。通过调用 Looper 类的 prepare 方法和 loop 方法,我们可以开始一个消息循环。在此循环中,我们可以根据不同的需求,使用自定义的 Handler 来处理消息逻辑。而 sendMessage 方法则是用于在 MyThread 中发送消息所用。
六、在主线程中使用 Handler
public class MainActivity extends AppCompatActivity { private MyThread myThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myThread = new MyThread(); myThread.start(); findViewById(R.id.btn_send_message).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Message msg = Message.obtain(); msg.what = 1; myThread.sendMessage(msg); } }); } }
可以看到,MainActivity 中的 onCreate 方法中创建了一个 MyThread 线程,并在点击按钮的回调中发送了一个携带了消息类型为1的消息,这样就能够在子线程中执行对应的逻辑操作了。
七、总结
本文以 Android 中消息机制的核心类 Looper、Message 和 Handler 为中心,详细介绍了消息循环、消息获取、消息分发过程,还有如何在子线程中创建 Looper、Handler,以及如何在主线程中发送消息触发相应的处理操作。只有充分理解 Android 的消息机制,才能更好的进行多线程编程,提高应用程序的性能与良好交互体验。