Android主线程与子线程之间的通信

Android中主线程与子线的通信往往会使用到Handler,Looper,MessageQueen,Message。首先简单的来介绍下他们在通信之间中的作用,以及相关使用方法。


Handler:相当于消息队列中具体处理消息的工人。可以有多个
Looper:相当于消息队列中的管家。只有1个。
MessageQueen:存放消息的队列。
Message:传递信息的消息体

它就像一个消息队列(MessageQueue)的管家(Looper),一个消息队列只有一个管家,并且管理者整个消息队列,而一个消息队列内可以容纳多个消息(Message),而工人(Handler)也可以有多个,管家派遣他们向消息队列中存储或取出消息后执行任务;所以它们的个数如下: 

管家(Looper): 1 个; 

消息队列(MessageQueue):1 个; 
消息(Message):可以多个; 
工人(Handler):可以多个;

 1. 主线程往子线程中发消息:

由于子线程中并没有消息队列,所以首先需要初始化消息队列(Looper.prepare()),以及启动消息循环(Looper.loop())。只有这样才能在子线程中使用Handler来捕获从主线程传过来的消息。详细的请看下面代码,实现了主线程发送一条消息到子线程,子线程接收到消息后将值用Toast显示出来。

[java]  view plain  copy
  1. package com.vic.demo;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.os.Looper;  
  7. import android.os.Message;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10. import android.widget.Button;  
  11. import android.widget.TextView;  
  12. import android.widget.Toast;  
  13.   
  14. public class TextActivity extends Activity{  
  15.     /** 
  16.      * 主线程发送消息到子线程 
  17.      */  
  18.     //主线程发送消息到子线程按钮  
  19.     private Button mButton = null;  
  20.     //子线程更新textView的值  
  21.     private TextView mText = null;  
  22.       
  23.     private int num = 0;  
  24.       
  25.     @Override  
  26.     protected void onCreate(Bundle savedInstanceState) {  
  27.         super.onCreate(savedInstanceState);  
  28.         super.setContentView(R.layout.text_layout);  
  29.           
  30.           
  31.         mButton = (Button) findViewById(R.id.send_msg_sub_thread);  
  32.         mText = (TextView) findViewById(R.id.update_text);  
  33.           
  34.         final SubThread subThread = new SubThread();  
  35.         subThread.start();  
  36.   
  37.         mButton.setOnClickListener(new OnClickListener() {  
  38.               
  39.             @Override  
  40.             public void onClick(View v) {  
  41.                 Message msg = Message.obtain();  
  42.                 msg.arg1 = num ;  
  43.                 subThread.subHandler.sendMessage(msg);  
  44.                 num ++;  
  45.             }  
  46.         });  
  47.     }  
  48.       
  49.       
  50.     private class SubThread extends Thread{  
  51.         Handler subHandler = null;  
  52.         @Override  
  53.         public void run() {  
  54.             //初始化looper  
  55.             Looper.prepare();  
  56.             subHandler = new Handler(){  
  57.                 @Override  
  58.                 public void handleMessage(Message msg) {  
  59.                     Toast.makeText(TextActivity.this"子线程收到消息:" + msg.arg1, Toast.LENGTH_SHORT).show();  
  60.                 }  
  61.             };  
  62.             //启动消息循环  
  63.             Looper.loop();  
  64.         }  
  65.     }     
  66. }  
[java]  view plain  copy
  1. package com.vic.demo;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.os.Looper;  
  7. import android.os.Message;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10. import android.widget.Button;  
  11. import android.widget.TextView;  
  12. import android.widget.Toast;  
  13.   
  14. public class TextActivity extends Activity{  
  15.     /** 
  16.      * 主线程发送消息到子线程 
  17.      */  
  18.     //主线程发送消息到子线程按钮  
  19.     private Button mButton = null;  
  20.     //子线程更新textView的值  
  21.     private TextView mText = null;  
  22.       
  23.     private int num = 0;  
  24.       
  25.     @Override  
  26.     protected void onCreate(Bundle savedInstanceState) {  
  27.         super.onCreate(savedInstanceState);  
  28.         super.setContentView(R.layout.text_layout);  
  29.           
  30.           
  31.         mButton = (Button) findViewById(R.id.send_msg_sub_thread);  
  32.         mText = (TextView) findViewById(R.id.update_text);  
  33.           
  34.         final SubThread subThread = new SubThread();  
  35.         subThread.start();  
  36.   
  37.         mButton.setOnClickListener(new OnClickListener() {  
  38.               
  39.             @Override  
  40.             public void onClick(View v) {  
  41.                 Message msg = Message.obtain();  
  42.                 msg.arg1 = num ;  
  43.                 subThread.subHandler.sendMessage(msg);  
  44.                 num ++;  
  45.             }  
  46.         });  
  47.     }  
  48.       
  49.       
  50.     private class SubThread extends Thread{  
  51.         Handler subHandler = null;  
  52.         @Override  
  53.         public void run() {  
  54.             //初始化looper  
  55.             Looper.prepare();  
  56.             subHandler = new Handler(){  
  57.                 @Override  
  58.                 public void handleMessage(Message msg) {  
  59.                     Toast.makeText(TextActivity.this"子线程收到消息:" + msg.arg1, Toast.LENGTH_SHORT).show();  
  60.                 }  
  61.             };  
  62.             //启动消息循环  
  63.             Looper.loop();  
  64.         }  
  65.     }     
  66. }  

代码执行结果如下图所示:

 

2. 子线程往主线程中发消息:

子线程往主线程中发送消息就比较简单了,因为在主线程中默认已经实现了消息队列。即已经实现了Looper.prepare()以及Looper.loop(),所以我们直接从子线程发送消息后,主线程用handler接收就可以了。下面的代码实现了在主线程中启动了一个子线程,子线程向主线程发送消息后,主线程更新textview的操作。

[cpp]  view plain  copy
  1. package com.vic.thread;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.os.Looper;  
  7. import android.os.Message;  
  8. import android.widget.TextView;  
  9.   
  10. import com.vic.demo.R;  
  11.   
  12. public class Sub2MainThread extends Activity{  
  13.     private TextView mText = null;  
  14.       
  15.     Handler mainHandler = null;  
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.sub2main);  
  20.         mText = (TextView) findViewById(R.id.main_text);  
  21.         //子线程启动  
  22.         new SubThread().start();  
  23.         //接收子线程发送过来消息,并更新UI  
  24.         mainHandler = new Handler(){  
  25.             @Override  
  26.             public void handleMessage(Message msg) {  
  27.                 super.handleMessage(msg);  
  28.                 mText.setText("从子线程接收到的消息为:" + msg.arg1);  
  29.             }  
  30.         };  
  31.     }  
  32.       
  33.     class SubThread extends Thread{  
  34.         @Override  
  35.         public void run() {  
  36.             super.run();  
  37.             Message msg = Message.obtain();  
  38.             msg.arg1 = 1;  
  39.             mainHandler.sendMessage(msg);  
  40.         }  
  41.     }  
  42.       
  43. }  
[cpp]  view plain  copy
  1. package com.vic.thread;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.os.Looper;  
  7. import android.os.Message;  
  8. import android.widget.TextView;  
  9.   
  10. import com.vic.demo.R;  
  11.   
  12. public class Sub2MainThread extends Activity{  
  13.     private TextView mText = null;  
  14.       
  15.     Handler mainHandler = null;  
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.sub2main);  
  20.         mText = (TextView) findViewById(R.id.main_text);  
  21.         //子线程启动  
  22.         new SubThread().start();  
  23.         //接收子线程发送过来消息,并更新UI  
  24.         mainHandler = new Handler(){  
  25.             @Override  
  26.             public void handleMessage(Message msg) {  
  27.                 super.handleMessage(msg);  
  28.                 mText.setText("从子线程接收到的消息为:" + msg.arg1);  
  29.             }  
  30.         };  
  31.     }  
  32.       
  33.     class SubThread extends Thread{  
  34.         @Override  
  35.         public void run() {  
  36.             super.run();  
  37.             Message msg = Message.obtain();  
  38.             msg.arg1 = 1;  
  39.             mainHandler.sendMessage(msg);  
  40.         }  
  41.     }  
  42.       
  43. }  
代码执行结果如下

总结:android主线程与子线程之间的通信往往是通过handler,Looper以及message来实现的。关键在于如果线程中没有实现消息队列的机制,需要通过调用Looper.prepare()以及Looper.loop()来建立好消息传送的通道。而主线程默认已经实现了消息 队列的相关机制,就不需要再进行消息初始化的操作了,直接调用handler的handleMessage方法来处理从子线程传递过来的消息。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值