原理
在一个循环下有多个线程,当一个线程休眠时另一个线程如何唤醒的呢? 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();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Looper.loop();
}
public Looper getLooper() {
if(!isAlive()) {
return null;
}
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) {
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();
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);
}
private static Message getPostMessage(Runnable r) {
Message m = Message.obtain();
m.callback = r;
return m;
}
|