• Android----Thread+Handler 线程 消息循环(转载)


    近来找了一些关于android线程间通信的资料,整理学习了一下,并制作了一个简单的例子。 

     andriod提供了 Handler 和 Looper 来满足线程间的通信。例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的。 

    在Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个事android的新 概念。我们的主线程(UI线程)就是一个消息循环的线程。针对这种消息循环的机制,我们引入一个新的机制Handle,我们有消息循环,就要往消息循环里 面发送相应的消息,自定义消息一般都会有自己对应的处理,消息的发送和清除,消息的的处理,把这些都封装在Handle里面,注意Handle只是针对那 些有Looper的线程,不管是UI线程还是子线程,只要你有Looper,我就可以往你的消息队列里面添加东西,并做相应的处理。 
    但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。 
      在Android,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个是android的新概念。我们的主线程(UI线程)就是一个消息循环的线程。针对这种消息循环的机制,我们引入一个新的机制Handler,我们有消息循环,就要往消息循环里面发送相应的消息,自定义消息一般都会有自己对应的处理,消息的发送和清除,把这些都封装在Handler里面,注意Handler只是针对那 些有Looper的线程,不管是UI线程还是子线程,只要你有Looper,我就可以往你的消息队列里面添加东西,并做相应的处理。 

    但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。 


      一个Handler的创建它就会被绑定到这个线程的消息队列中,如果是在主线程创建的,那就不需要写代码来创建消息队列了,默认的消息队列会在主线程被创建。但是如果是在子线程的话,就必须在创建Handler之前先初始化线程的消息队列。如下面的代码: 

    Java代码  收藏代码
    1. class ChildThread extends Thread {  
    2.   
    3.     public void run() {  
    4.   
    5.         /* 
    6.          * 创建 handler前先初始化Looper. 
    7.          */  
    8.         Looper.prepare();  
    9.   
    10.         /* 
    11.          * 在子线程创建handler,所以会绑定到子线程的消息队列中 
    12.          * 
    13.          */  
    14.         mChildHandler = new Handler() {  
    15.   
    16.             public void handleMessage(Message msg) {  
    17.   
    18.                 /* 
    19.                  * Do some expensive operations there. 
    20.                  */  
    21.             }  
    22.         };  
    23.   
    24.         /* 
    25.          * 启动该线程的消息队列 
    26.          */  
    27.         Looper.loop();  
    28.     }  
    29. }  

     



    当Handler收到消息后,就会运行handleMessage(…)的回调函数,可以在里面做一些耗时的操作。 




    最后完成了操作要结束子线程时,记得调用quit()来结束消息循环队列。 

    mChildHandler.getLooper().quit(); 



    下面是一个线程间通信的小例子: 

    Java代码  收藏代码
      1. /** 
      2.  *  
      3.  * @author allin.dev  
      4.  * http://allin.cnblogs.com 
      5.  *  
      6.  */  
      7. public class MainThread extends Activity {  
      8.   
      9.     private static final String TAG = "MainThread";  
      10.     private Handler mMainHandler, mChildHandler;  
      11.     private TextView info;  
      12.     private Button msgBtn;  
      13.   
      14.     @Override  
      15.     public void onCreate(Bundle savedInstanceState) {  
      16.         super.onCreate(savedInstanceState);  
      17.         setContentView(R.layout.main);  
      18.   
      19.         info = (TextView) findViewById(R.id.info);  
      20.         msgBtn = (Button) findViewById(R.id.msgBtn);  
      21.   
      22.         mMainHandler = new Handler() {  
      23.   
      24.             @Override  
      25.             public void handleMessage(Message msg) {  
      26.                 Log.i(TAG, "Got an incoming message from the child thread - "  
      27.                         + (String) msg.obj);  
      28.                 // 接收子线程的消息  
      29.                 info.setText((String) msg.obj);  
      30.             }  
      31.   
      32.         };  
      33.   
      34.         new ChildThread().start();  
      35.           
      36.           
      37.         msgBtn.setOnClickListener(new OnClickListener() {  
      38.   
      39.             @Override  
      40.             public void onClick(View v) {  
      41.                   
      42.                 if (mChildHandler != null) {  
      43.                       
      44.                     //发送消息给子线程  
      45.                     Message childMsg = mChildHandler.obtainMessage();  
      46.                     childMsg.obj = mMainHandler.getLooper().getThread().getName() + " says Hello";  
      47.                     mChildHandler.sendMessage(childMsg);  
      48.                       
      49.                     Log.i(TAG, "Send a message to the child thread - " + (String)childMsg.obj);  
      50.   
      51.   
      52.                 }  
      53.             }  
      54.         });  
      55.   
      56.     }  
      57.   
      58.     public void onDestroy() {  
      59.       super.onDestroy();  
      60.         Log.i(TAG, "Stop looping the child thread's message queue");  
      61.   
      62.         mChildHandler.getLooper().quit();  
      63.     }  
      64.   
      65.     class ChildThread extends Thread {  
      66.   
      67.         private static final String CHILD_TAG = "ChildThread";  
      68.   
      69.         public void run() {  
      70.             this.setName("ChildThread");  
      71.   
      72.             //初始化消息循环队列,需要在Handler创建之前  
      73.             Looper.prepare();  
      74.   
      75.             mChildHandler = new Handler() {  
      76.                 @Override  
      77.                 public void handleMessage(Message msg) {  
      78.                      Log.i(CHILD_TAG, "Got an incoming message from the main thread - " + (String)msg.obj);  
      79.   
      80.   
      81.                     try {  
      82.   
      83.                         //在子线程中可以做一些耗时的工作  
      84.                         sleep(100);  
      85.   
      86.                         Message toMain = mMainHandler.obtainMessage();  
      87.                         toMain.obj = "This is " + this.getLooper().getThread().getName() +  
      88.                                     ".  Did you send me "" + (String)msg.obj + ""?";  
      89.   
      90.                         mMainHandler.sendMessage(toMain);  
      91.   
      92.                         Log.i(CHILD_TAG, "Send a message to the main thread - " + (String)toMain.obj);  
      93.   
      94.                     } catch (InterruptedException e) {  
      95.                         // TODO Auto-generated catch block  
      96.                         e.printStackTrace();  
      97.                     }  
      98.                 }  
      99.   
      100.             };  
      101.   
      102.             Log.i(CHILD_TAG, "Child handler is bound to - "+ mChildHandler.getLooper().getThread().getName());  
      103.   
      104.             //启动子线程消息循环队列  
      105.             Looper.loop();  
      106.         }  
      107.     }  
      108. }  
  • 相关阅读:
    设计模式大赛 -- 大话设计模式
    访问者模式 -- 大话设计模式
    puts的用处
    scanf的使用
    iOS,手势识别简单使用
    iOS,多媒体,地图相关
    iOS,文本输入,键盘相关
    iOS,XMPP本地环境搭建和框架使用
    iOS,自动布局autoresizing和auto layout,VFL语言
    iOS,图片处理
  • 原文地址:https://www.cnblogs.com/xiaochao1234/p/4095399.html
Copyright © 2020-2023  润新知