欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-14 07:50:08
...

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中处理了。流程示意图如下:
Android中的消息机制二(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中执行了。