默认情况下新增的线程是没有开启消息循环的(主线程除外,会默认创建Looper对象,开启消息循环)
一般情况下都是子线程向主线程发送消息,主线程中已经默认实现了Looper的操作。只需要创建Handler 开启线程发送消息 主线程中接收消息处理就可以了
Looper:消息队列(MessageQueue)的管家(Looper)。一个消息队列只有一个管家,但是Handler(工人)可以有多个。Looper管理者handler向MessageQueue中存储和取出消息之后执行任务。
所以他们的个数:
管家(Looper): 1 个;
消息队列(MessageQueue):1 个;
消息(Message):可以多个;
工人(Handler):可以多个;
而这里研究的是主线程向子线程发送消息,所以要在子线程中创建Handler必须用到Looper。
Looper.prepare()来给线程创建一个消息循环,Looper.loop()让Looper开始工作,从消息队列里取消息,处理消息。
注意:写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。
主线程和子线程通信:
public class MainActivity2 extends BaseActivity {
Button buttonMainToChild;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//onCreate中默认开启线程 LooperThread
//线程创建是一个耗时的操作 如果放到click中创建的话 紧接着发送消息的话 可能handler还没创建就已经发送消息了
//click方法中只是发送消息
final LooperThread looperThread = new LooperThread();
new Thread(looperThread).start();
buttonMainToChild = (Button) findViewById(R.id.button_main_to_child);
buttonMainToChild.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message msMessage = new Message();
msMessage.arg1 = 3;
looperThread.handler.sendMessage(msMessage);
}
});
}
//LooperThread
class LooperThread implements Runnable {
public Handler handler;
@Override
public void run() {
Looper.prepare();
handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG, "handleMessage: LooperThread 消息是:" + msg.arg1);
}
};
Looper.loop();
}
}
}
注意:
1、Handler的创建是在子线程中,调用的时候也得注意是子线程中的handler
2、这里默认是在onCreate中开启线程,在onclick中发送消息。线程创建是一个耗时的操作 如果放到click中创建的话 紧接着发送消息的话 可能handler还没创建就已经发送消息了
HandlerThread实现主线程和子线程通信:
Button buttonMainToChild2;
private Handler mHandler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
buttonMainToChild2 = (Button) findViewById(R.id.button_main_to_child2);
buttonMainToChild2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//实例化一个特殊的线程HandlerThread,必须给其指定一个名字
HandlerThread handlerThread = new HandlerThread("王灵生");
handlerThread.start();
//将 mHandler 与 Thread 相关联
mHandler = new Handler(handlerThread.getLooper()){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Log.d(TAG, "handleMessage: 当前子线程是----->" + Thread.currentThread());
}
};
mHandler.sendEmptyMessage(1);
}
});
}
Handler是一个包含Looper的Thread 可以使用这个Looper创建Handler,HandleMessage所在的线程就是HandlerThread的子线程。
子线程和子线程通信
第一个子线程里创建handler,开启Looper轮训
第二个子线程当中调用这个handler发送消息就可以了。
Button button_child_to_child;
Button button_child_to_child2;
private Handler childHandler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
button_child_to_child = (Button) findViewById(R.id.button_child_to_child);
button_child_to_child.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//创建第一个子线程
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
childHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
System.out.println("这个消息是从-->>" + msg.obj + "过来的,在" + "btn的子线程当中" + "中执行的");
}
};
Looper.loop(); //开始轮询
}
}).start();
}
});
button_child_to_child2 = (Button) findViewById(R.id.button_child_to_child2);
button_child_to_child2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//第二个子线程 发送消息
new Thread(new Runnable() {
@Override
public void run() {
//发送消息
Message message = childHandler.obtainMessage();
message.obj = "btn2当中子线程";
childHandler.sendMessage(message);
}
}).start();
}
});