Android消息处理机制

原理

在一个循环下有多个线程,当一个线程休眠时另一个线程如何唤醒的呢?
在这里插入图片描述
1、通过epoll机制,当没有数据时就休眠,有数据就立刻唤醒。

2、A线程不断地发送消息给B线程,当B线程消息处理不过来时,得用消息队列
在这里插入图片描述

分析源码:

  • 创建MessageQueue,用Looper.prepare
    在这里插入图片描述当前线程中,设置 new looper,创建looper的实例化对象在这里插入图片描述
    并在looper中创建了消息队列
  • .使用Handler构造消息,发送消息
    在这里插入图片描述
    有很多不同的构造方法,Callback是回调函数就是那些消息的处理函数,Looper是消息的接收者

在这里插入图片描述
发送消息函数

  • 使用Loop循环处理,从MessageQueue中读取消息,然后执行
    Looper.java
    Looper中循环处理消息。

处理过程,在loop中有个for循环,从队列里面拿出消息,当找到msg后调用dispatchMessage(msg)去处理msg。其中的target为handler。
在这里插入图片描述
在handler中调用callback来处理,此callback为注册handler时所注册的handler。注意如果msg中没有携带callback,则使用handler里面构造的callback。
在这里插入图片描述

DEMO例子

package com.example.app_handlemessage;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.os.HandlerThread;

public class MainActivity extends AppCompatActivity {

    private Button mButton;
    private final String TAG = "MessageTest";
    private Thread myThread;
    private MyThread mythread2;
    private Handler mHandler;

    private HandlerThread myThread3;
    private Handler mHandler3;
    class MyRunnable implements Runnable {
        @Override
        public void run() {
            for(;;)
            {
                Log.d(TAG, "MyThread");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    class MyThread extends Thread {
        private Looper mLooper;
        @Override
        public void run() {
            super.run();
            Looper.prepare();//这里面会去创建messagequeue队列
            synchronized (this) {
                mLooper = Looper.myLooper();
                notifyAll();
            }
            Looper.loop();//这里会去messagequeue中循环处理消息
        }
        public Looper getLooper() {
            if(!isAlive()) {
                return null;
            }
            //这里防止其他线程先调用getLooper函数,后才执行run()函数,从而使得looper还没初始化
            synchronized (this) {
                while (isAlive() && mLooper == null) {
                    try {
                        wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
            return mLooper;
        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButton = (Button)findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                // Perform action on click
                Message msg = new Message();
                mHandler.sendMessage(msg);

                mHandler3.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.d(TAG, "handleMessage3");
                    }
                });
            }
        });
        myThread = new Thread(new MyRunnable(),"MessageTestThread");
        myThread.start();
        //这个线程具有处理消息的能力
        mythread2 = new MyThread();
        mythread2.start();
        //将handler和looper绑定一起,handler发消息的时候是发给这个looper,当looper收到消息的时候,会调用这个callback来处理
        mHandler = new Handler(mythread2.getLooper(), new Handler.Callback(){

            @Override
            public boolean handleMessage(@NonNull Message msg) {
                Log.d(TAG, "handleMessage");
                return false;
            }
        });

        myThread3 = new HandlerThread("messageTestThread3");
        myThread3.start();
        mHandler3 = new Handler(myThread3.getLooper());
    }
}

以上示例中,开辟了两个线程mythread2,mythread3去处理队列消息。
其中mythread2是自己实现的一个线程去处理。其中通过mHandler.sendMessage(msg)发送消息,收到后处理的是
handler中自带的callback

mHandler = new Handler(mythread2.getLooper(), new Handler.Callback(){

            @Override
            public boolean handleMessage(@NonNull Message msg) {
                Log.d(TAG, "handleMessage");
                return false;
            }
        });

mythread3是使用handlethread去处理,其中通过mHandler3.post(new Runnable())去投递消息,收到后处理的是message的回调函数。

mHandler3.post(new Runnable() {
                    @Override
                    public void run() {
                        Log.d(TAG, "handleMessage3");
                    }
                });

发现post方法如下:

public final boolean post(@NonNull Runnable r) {
       return  sendMessageDelayed(getPostMessage(r), 0);
    }
//最终Runnable还是放到Message的callback去
private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值