Andriod提供了 Handler 和 Looper 来满足线程间的通信。
Android不允许UI线程之外的线程改变UI组件的值,所以要想在其他线程里面改变UI组件的值,必须使用Handler来实现。
1)Looper: 一个线程可以产生一个Looper对象,由它来管理此线程里的Message Queue(消息队列)。
2)Handler: 你可以构造Handler对象来与Looper沟通,以便push(上传)新消息到Message Queue里;或者接收Looper从Message Queue取出的消息。
3) Message Queue(消息队列):用来存放线程放入的消息。
4)线程:UI thread 通常就是main thread,而Android启动程序时会替它建立一个Message Queue。
Handler、Looper、MessageQueue的初始化流程如下所示。
Hander持有对UI主线程消息队列UI_MQ和消息循环Looper的引用,子线程可以通过Handler将消息发送到UI线程的消息队列UI_MQ中。
Handler处理消息
UI主线程通过Looper循环查询消息队列UI_MQ,当发现有消息存在时会将消息从消息队列中取出。首先分析消息,通过消息的参数判断该消息对应的Handler,然后将消息分发到指定的Handler进行处理。
下面是示例代码:
其中包含
主线程发送消息子线程接收
子线程发送消息子线程接收
子线程发送消息主线程接收
public class MainActivity extends AppCompatActivity {
//主线程、子线程向子线程发送消息
private Handler handler;
//子线程向主线程发送消息
private Handler handler1;
private Button sendMsgBySubThread;
private Button sendMsgByMainThread;
private Button sendMsgBySubThreadToMainThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sendMsgBySubThread = (Button) findViewById(R.id.start);
sendMsgByMainThread = (Button) findViewById(R.id.sendMsg);
sendMsgBySubThreadToMainThread = (Button) findViewById(R.id.sendMsg1);
//开启子线程接收者
new MyThread().start();
//开启主线程接收者
handler1 = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
Log.i("MainActivity","-------->" + message.what + "主线程接收");
Log.i("MainActivity","-------->" + message.obj);
return false;
}
});
//主线程发送,子线程接收
sendMsgByMainThread.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(handler != null){
//handler.sendEmptyMessage(200);
Message message = handler.obtainMessage();
message.what = 200;
message.obj = "我是主线程发送者";
handler.sendMessage(message);
}
}
});
//子线程发送子线程接收
sendMsgBySubThread.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//启动子线程发送消息
new MySecondThread().start();
}
});
//子线程发送主线程接收
sendMsgBySubThreadToMainThread.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new MyThirdThread().start();
}
});
}
//子线程接收消息
public class MyThread extends Thread{
@Override
public void run() {
super.run();
//子线程构建Looper对象
Looper.prepare();
handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message message) {
Log.i("MainActivity","-------->" + message.what + "子线程接收者");
Log.i("MainActivity","-------->" + message.obj);
return false;
}
}) {
};
//子线程中启动无限循环取消息
Looper.loop();
}
}
//子线程发送消息子线程接收
public class MySecondThread extends Thread{
@Override
public void run() {
super.run();
if(handler != null){
//发送空消息
//handler.sendEmptyMessage(1000);
//发送其他消息
Message message = handler.obtainMessage();
message.what = 1000;
message.obj = "我是子线程发送者,发送给子线程";
handler.sendMessage(message);
}
}
}
//子线程发送主线程接收
public class MyThirdThread extends Thread{
@Override
public void run() {
super.run();
if (handler1 != null){
Message message = handler1.obtainMessage();
message.what = 400;
message.obj = "我是子线程发送者,发送给主线程";
handler1.sendMessage(message);
}
}
}
}