Android中的消息机制二(Handler的工作过程)

Handler工作过程

上篇文章中介绍了Handler、Looper、ThreadLocal、MessageQueue这四个类,下面介绍一下Handler的工作过程,也是消息在线程之间通过Handler进行传递的过程。

假设有两个线程分别是Thread1和Thread2,现在需要把Thread2中的一个任务切换到Thread1中去执行。首先创建一个属于线程Thread1的Handler,然后在另一个线程Thread2中拿到该Handler对象的引用,并调用该Handler发送消息到Handler的消息队列中,然后在由Handler对应的Looper取出该消息交给该Handler的dispatchMessage(在Handler对应的线程里面执行的,也就是线程1)方法分发处理该消息,这样任务就从Thread2切换到Thread1中处理了。流程示意图如下:
Handler消息传递流程

下面结合代码来验证上述过程:

Thread1代码:

package com.example.lx_rl.handlerdemo;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

/**
 * 作者:znh on 2018/6/11 11:18
 */
public class Thread1 extends Thread {

    //在run方法中创建属于Thread1的Handler对象
    private Handler mHandler;

    @Override
    public void run() {
        super.run();
        //创建Thread1的Looper
        Looper.prepare();

        //创建Thread1的Handler对象
        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                Log.e("znh", "handleMessage..." + Thread.currentThread().getName());
            }
        };

        //开启Looper循环
        Looper.loop();
    }

    public void sendMsg() {
        if (mHandler != null) {
            Log.e("znh", "sendMsg..." + Thread.currentThread().getName());
            mHandler.sendEmptyMessage(0);
        }
    }
}

Thread2代码:

package com.example.lx_rl.handlerdemo;

/**
 * 作者:znh on 2018/6/11 11:34
 */
public class Thread2 extends Thread {

    //Thread1的引用
    private Thread1 mThread1;

    public void setThread1(Thread1 mThread1) {
        this.mThread1 = mThread1;
    }

    @Override
    public void run() {
        super.run();
        try {
            //在Thread2中,调用Thread1的handler发送消息
            Thread.sleep(2000);
            mThread1.sendMsg();
        } catch (Exception e) {

        }
    }
}

执行代码:

//创建两个线程
Thread1 thread1 = new Thread1();
Thread2 thread2 = new Thread2();

//打印两个线程的名称
Log.e("znh", "thread1..." + thread1.getName());
Log.e("znh", "thread2..." + thread2.getName());

//开始执行
thread2.setThread1(thread1);
thread1.start();
thread2.start();

执行结果:

 thread1...Thread-8503
 thread2...Thread-8504
 sendMsg...Thread-8504
 handleMessage...Thread-8503

通过上面的执行结果可知:

  • Thread1的线程名称是Thread-8503,Thread2的线程名称是Thread-8504。
  • 消息发送(sendMsg)是在线程名称为Thread-8504的线程中执行的,由线程名称可知该线程是Thread2。
  • 而消息处理(handleMessage)是在线程名称为Thread-8503的线程中执行的,由线程名称可知该线程是Thread1。

所以Thread2中的任务成功的切换到了Thread1中执行了。

猜你喜欢

转载自blog.csdn.net/huideveloper/article/details/80655357