前一篇篇幅限制,分割成了两篇。本篇将用示例演示主线程到子线程、子线程到主线程、子线程到子线程三种进程通讯方式。
如果对ThreadLocal ,Looper,Handler不了解的,可以去看我的上篇文章:
Handler消息传递详解-主线程到子线程、子线程到主线程、子线程到子线程 (一)
代码是最好的表述,就直接先上代码吧。
MainActivity代码
public class MainActivity extends AppCompatActivity {
private Handler mMainHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==Constants.SUB1_2_MAIN){
System.out.println("I am from Sub thread");
System.out.println("thread="+Thread.currentThread().getName());
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//子线程到主线程
testSub2Main();
//主线程到子线程
testMain2Sub();
//子线程到子线程
testSub2Sub();
}
private void testSub2Sub() {
Runnable3 runnable3 = new Runnable3();
new Thread(runnable3).start(); //启动线程3
//注意:这里由于是线程异步,程序执行到这里的时候,子线程的run方法不一定执行完,可能会导致myLooper3为空,所以,这里循环等待,知道初始化完
while (true){
if(runnable3.myLooper3!=null){
Runnable4 runnable4 = new Runnable4(runnable3.handler3);
new Thread(runnable4).start();
return;
}
}
}
private void testMain2Sub() {
//主线程向子线程发消息
Runnable2 runnable2 = new Runnable2();
new Thread(runnable2).start(); //启动线程2
Message msg = new Message();
msg.what=Constants.MAIN_2_SUB2;
//注意:这里由于是线程异步,程序执行到这里的时候,子线程的run方法不一定执行完,可能会导致myLooper3为空,所以,这里循环等待,知道初始化完
while (true){
if(runnable2.mylooper2!=null){
runnable2.handler2.sendMessage(msg);
return;
}
}
}
private void testSub2Main() {
//子线程向主线程发消息
new Thread(new Runnable1(mMainHandler)).start();
}
}
Constants常量
public class Constants {
public static int SUB1_2_MAIN=0;
public static int MAIN_2_SUB2=1;
public static int SUB_2_SUB=2;
}
Runnable1
public class Runnable1 implements Runnable {
Handler handler;
public Runnable1(Handler handler){
this.handler = handler;
}
@Override
public void run() {
Message msg = new Message();
msg.what=Constants.SUB1_2_MAIN;
handler.sendMessage(msg);
}
}
Runnable2
public class Runnable2 implements Runnable {
public Looper mylooper2;
public Handler handler2;
@Override
public void run() {
Looper.prepare(); //创建一个新的looper,并将其放入sThreadLocal中
handler2= new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==Constants.MAIN_2_SUB2){
System.out.println("I am from main thread");
System.out.println("thread="+Thread.currentThread().getName());
}
}
};
mylooper2 = Looper.myLooper();//从threadlocal中取出当前线程的looper
Looper.loop();
}
}
Runnable3
public class Runnable3 implements Runnable {
public Handler handler3;
public Looper myLooper3 ;
@Override
public void run() {
Looper.prepare();
handler3= new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==Constants.SUB_2_SUB){
System.out.println("I am from other thread");
System.out.println("thread="+Thread.currentThread().getName());
}
}
};
myLooper3= Looper.myLooper();
Looper.loop();
}
}
Runnable4
public class Runnable4 implements Runnable {
Handler handler;
public Runnable4 (Handler handler){
this.handler = handler;
}
@Override
public void run() {
Message msg = new Message();
msg.what =Constants.SUB_2_SUB;
handler.sendMessage(msg);
}
}
运行起来看看结果:
那么改一下代码
public class Runnable3 implements Runnable {
public Handler handler3;
public Looper myLooper3 ;
@Override
public void run() {
Looper.prepare();
handler3= new Handler(Looper.getMainLooper()){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==Constants.SUB_2_SUB){
System.out.println("I am from other thread");
System.out.println("thread="+Thread.currentThread().getName());
}
}
};
myLooper3= Looper.myLooper();
Looper.loop();
}
}
在看运行效果:
是不是发现,明明在Thread3中的handler,却在MainThread中了。原因已经在上一篇中说明了。再说一下,那就是指定了Looper,则Looper所在线程就是Handler回调所在线程。
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
源码下载:
https://download.csdn.net/download/shoneworn/10437255