• Handler+Looper+MessageQueue-各大牛对Android异步处理的理解+我的个人想法


    一、几个关键概念

    1、MessageQueue:是一种数据结构,见名知义,就是一个消息队列,存放消息的地方。每一个线程最多只可以拥有一个MessageQueue数据结构。
    创建一个线程的时候,并不会自动创建其MessageQueue。通常使用一个Looper对象对该线程的MessageQueue进行管理。主线程创建时,会创建一
    个默认的Looper对象,而Looper对象的创建,将自动创建一个Message Queue。其他非主线程,不会自动创建Looper,要需要的时候,通过调
    用prepare函数来实现。

    1 final MessageQueue mQueue;
    2 private Looper() {
    3         mQueue = new MessageQueue();
    4         mRun = true;
    5         mThread = Thread.currentThread();
    6     }

    下面是prepare方法,静态方法

    1 private static final ThreadLocal sThreadLocal = new ThreadLocal();
    2 public static final void prepare() {
    3         if (sThreadLocal.get() != null) {
    4             throw new RuntimeException("Only one Looper may be created per thread");
    5         }
    6         sThreadLocal.set(new Looper());
    7 }

    2、Message:消息对象,Message Queue中的存放的对象。一个Message Queue中包含多个Message。
    Message实例对象的取得,

    通常使用Message类里的静态方法obtain(),

    该方法有多个重载版本可供选择;它的创建并不一定是直接创建一个新的实例,
    而是先从Message Pool(消息池)中看有没有可用的Message实例,存在则直接取出返回这个实例。如果Message Pool中没有可用的Message实例,
    则才用给定的参数创建一个Message对象。调用removeMessages()时,将Message从Message Queue中删除,同时放入到Message Pool中。除了上面这
    种方式,也可以通过Handler对象的obtainMessage()获取一个Message实例。

    3、Looper:
    是MessageQueue的管理者。每一个MessageQueue都不能脱离Looper而存在(正如刚1提到的,一个Looper对一个message对象管理),Looper对象的创建是通过prepare函数来实现的。同时每一个Looper对象
    和一个线程关联。通过调用Looper.myLooper()可以获得当前线程的Looper对象
    创建一个Looper对象时,会同时创建一个MessageQueue对象。除了主线程有默认的Looper,其他线程默认是没有MessageQueue对象的,所以,不能
    接受Message。如需要接受,自己定义一个Looper对象(通过prepare函数),这样该线程就有了自己的Looper对象和MessageQueue数据结构了。
    Looper从MessageQueue中取出Message然后,交由Handler的handleMessage进行处理。处理完成后,调用Message.recycle()将其放入Message Pool中。

    4、Handler:
    消息的处理者,handler负责将需要传递的信息封装成Message,通过调用handler对象的obtainMessage()来实现;
    将消息传递给Looper,这是通过handler对象的sendMessage()来实现的。继而由Looper将Message放入MessageQueue中。
    当Looper对象看到MessageQueue中含有Message,就将其广播出去。该handler对象收到该消息后,调用相应的handler对象的handleMessage()方法

      1 二、线程之间的消息如何进行传递
      2 
      3 1、主线程给自己发送Message
      4 
      5 package test.message;
      6 
      7 import android.app.Activity;
      8 import android.os.Bundle;
      9 import android.os.Handler;
     10 import android.os.Looper;
     11 import android.os.Message;
     12 import android.view.View;
     13 import android.widget.Button;
     14 import android.widget.TextView;
     15 
     16 public class MainActivity extends Activity {
     17     
     18     private Button btnTest;
     19     private TextView textView;
     20     
     21     private Handler handler;
     22     
     23     @Override
     24     public void onCreate(Bundle savedInstanceState) {
     25         super.onCreate(savedInstanceState);
     26         setContentView(R.layout.main);
     27         
     28         btnTest = (Button)this.findViewById(R.id.btn_01);
     29         textView = (TextView)this.findViewById(R.id.view_01);
     30         
     31         btnTest.setOnClickListener(new View.OnClickListener() {
     32             
     33             @Override
     34             public void onClick(View arg0) {
     35                 
     36                 Looper looper = Looper.getMainLooper(); //主线程的Looper对象
     37                 //这里以主线程的Looper对象创建了handler,
     38                 //所以,这个handler发送的Message会被传递给主线程的MessageQueue。
     39                 handler = new MyHandler(looper);
     40                 handler.removeMessages(0);
     41                 //构建Message对象
     42                 //第一个参数:是自己指定的message代号,方便在handler选择性地接收
     43                 //第二三个参数没有什么意义
     44                 //第四个参数需要封装的对象
     45                 Message msg = handler.obtainMessage(1,1,1,"主线程发消息了");
     46                 
     47                 handler.sendMessage(msg); //发送消息
     48                 
     49             }
     50         });
     51     }
     52     
     53     class MyHandler extends Handler{
     54         
     55         public MyHandler(Looper looper){
     56             super(looper);
     57         }
     58         
     59         public void handleMessage(Message msg){
     60             super.handleMessage(msg);
     61             textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj);
     62         }
     63     }
     64 }
     65 
     66 2、其他线程给主线程发送Message
     67 
     68 package test.message;
     69 
     70 import android.app.Activity;
     71 import android.os.Bundle;
     72 import android.os.Handler;
     73 import android.os.Looper;
     74 import android.os.Message;
     75 import android.view.View;
     76 import android.widget.Button;
     77 import android.widget.TextView;
     78 
     79 public class MainActivity extends Activity {
     80     
     81     private Button btnTest;
     82     private TextView textView;
     83     
     84     private Handler handler;
     85     
     86     @Override
     87     public void onCreate(Bundle savedInstanceState) {
     88         super.onCreate(savedInstanceState);
     89         setContentView(R.layout.main);
     90         
     91         btnTest = (Button)this.findViewById(R.id.btn_01);
     92         textView = (TextView)this.findViewById(R.id.view_01);
     93         
     94         btnTest.setOnClickListener(new View.OnClickListener() {
     95             
     96             @Override
     97             public void onClick(View arg0) {
     98                 
     99                 //可以看出这里启动了一个线程来操作消息的封装和发送的工作
    100                 //这样原来主线程的发送就变成了其他线程的发送,简单吧?呵呵
    101                 new MyThread().start();    
    102             }
    103         });
    104     }
    105     
    106     class MyHandler extends Handler{
    107         
    108         public MyHandler(Looper looper){
    109             super(looper);
    110         }
    111         
    112         public void handleMessage(Message msg){
    113             super.handleMessage(msg);
    114             textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj);
    115         }
    116     }
    117     
    118     //加了一个线程类
    119     class MyThread extends Thread{
    120         
    121         public void run(){
    122             Looper looper = Looper.getMainLooper(); //主线程的Looper对象
    123             //这里以主线程的Looper对象创建了handler,
    124             //所以,这个handler发送的Message会被传递给主线程的MessageQueue。
    125             handler = new MyHandler(looper);
    126 
    127             //构建Message对象
    128             //第一个参数:是自己指定的message代号,方便在handler选择性地接收
    129             //第二三个参数没有什么意义
    130             //第四个参数需要封装的对象
    131             Message msg = handler.obtainMessage(1,1,1,"其他线程发消息了");
    132             
    133             handler.sendMessage(msg); //发送消息            
    134         }
    135     }
    136 }
    137 
    138 3、主线程给其他线程发送Message
    139 
    140 package test.message;
    141 
    142 import android.app.Activity;
    143 import android.os.Bundle;
    144 import android.os.Handler;
    145 import android.os.Looper;
    146 import android.os.Message;
    147 import android.view.View;
    148 import android.widget.Button;
    149 import android.widget.TextView;
    150 
    151 public class MainActivity extends Activity {
    152     
    153     private Button btnTest;
    154     private TextView textView;
    155     
    156     private Handler handler;
    157     
    158     @Override
    159     public void onCreate(Bundle savedInstanceState) {
    160         super.onCreate(savedInstanceState);
    161         setContentView(R.layout.main);
    162         
    163         btnTest = (Button)this.findViewById(R.id.btn_01);
    164         textView = (TextView)this.findViewById(R.id.view_01);
    165         
    166         
    167         //启动线程
    168         new MyThread().start();    
    169         
    170         btnTest.setOnClickListener(new View.OnClickListener() {
    171             
    172             @Override
    173             public void onClick(View arg0) {
    174                 //这里handler的实例化在线程中
    175                 //线程启动的时候就已经实例化了
    176                 Message msg = handler.obtainMessage(1,1,1,"主线程发送的消息");
    177                 handler.sendMessage(msg);
    178             }
    179         });
    180     }
    181     
    182     class MyHandler extends Handler{
    183         
    184         public MyHandler(Looper looper){
    185             super(looper);
    186         }
    187         
    188         public void handleMessage(Message msg){
    189             super.handleMessage(msg);
    190             textView.setText("我是主线程的Handler,收到了消息:"+(String)msg.obj);
    191         }
    192     }
    193     
    194     class MyThread extends Thread{
    195         
    196         public void run(){
    197             Looper.prepare(); //创建该线程的Looper对象,用于接收消息
    198             
    199             //注意了:这里的handler是定义在主线程中的哦,呵呵,
    200             //前面看到直接使用了handler对象,是不是在找,在什么地方实例化的呢?
    201             //现在看到了吧???呵呵,开始的时候实例化不了,因为该线程的Looper对象
    202             //还不存在呢。现在可以实例化了
    203             //这里Looper.myLooper()获得的就是该线程的Looper对象了
    204             handler = new ThreadHandler(Looper.myLooper());
    205             
    206             //这个方法,有疑惑吗?
    207             //其实就是一个循环,循环从MessageQueue中取消息。
    208             //不经常去看看,你怎么知道你有新消息呢???
    209             Looper.loop(); 
    210 
    211         }
    212         
    213         //定义线程类中的消息处理类
    214         class ThreadHandler extends Handler{
    215             
    216             public ThreadHandler(Looper looper){
    217                 super(looper);
    218             }
    219             
    220             public void handleMessage(Message msg){
    221                 //这里对该线程中的MessageQueue中的Message进行处理
    222                 //这里我们再返回给主线程一个消息
    223                 handler = new MyHandler(Looper.getMainLooper());
    224                 
    225                 Message msg2 = handler.obtainMessage(1,1,1,"子线程收到:"+(String)msg.obj);
    226                 
    227                 handler.sendMessage(msg2);
    228             }
    229         }
    230     }
    231 }
    232 
    233 4、其他线程给自己发送Message 
    234 
    235 package test.message;
    236 
    237 import android.app.Activity;
    238 import android.os.Bundle;
    239 import android.os.Handler;
    240 import android.os.Looper;
    241 import android.os.Message;
    242 import android.view.View;
    243 import android.widget.Button;
    244 import android.widget.TextView;
    245 
    246 public class MainActivity extends Activity {
    247     
    248     private Button btnTest;
    249     private TextView textView;
    250     
    251     private Handler handler;
    252     
    253     @Override
    254     public void onCreate(Bundle savedInstanceState) {
    255         super.onCreate(savedInstanceState);
    256         setContentView(R.layout.main);
    257         
    258         btnTest = (Button)this.findViewById(R.id.btn_01);
    259         textView = (TextView)this.findViewById(R.id.view_01);
    260         
    261         
    262         btnTest.setOnClickListener(new View.OnClickListener() {
    263             
    264             @Override
    265             public void onClick(View arg0) {
    266                 //启动线程
    267                 new MyThread().start();    
    268             }
    269         });
    270     }
    271     
    272     class MyHandler extends Handler{
    273         
    274         public MyHandler(Looper looper){
    275             super(looper);
    276         }
    277         
    278         public void handleMessage(Message msg){
    279             super.handleMessage(msg);
    280             textView.setText((String)msg.obj);
    281         }
    282     }    
    283     
    284     class MyThread extends Thread{
    285         
    286         public void run(){
    287             Looper.prepare(); //创建该线程的Looper对象
    288             //这里Looper.myLooper()获得的就是该线程的Looper对象了
    289             handler = new ThreadHandler(Looper.myLooper());
    290             Message msg = handler.obtainMessage(1,1,1,"我自己");
    291             handler.sendMessage(msg);
    292             
    293             Looper.loop(); 
    294 
    295         }
    296         
    297         //定义线程类中的消息处理类
    298         class ThreadHandler extends Handler{
    299             
    300             public ThreadHandler(Looper looper){
    301                 super(looper);
    302             }
    303             
    304             public void handleMessage(Message msg){
    305                 //这里对该线程中的MessageQueue中的Message进行处理
    306                 //这里我们再返回给主线程一个消息
    307                 //加入判断看看是不是该线程自己发的信息
    308                 if(msg.what == 1 && msg.obj.equals("我自己")){
    309                     
    310                     handler = new MyHandler(Looper.getMainLooper());
    311                     
    312                     Message msg2 = handler.obtainMessage(1,1,1,"禀告主线程:我收到了自己发给自己的Message");
    313                     
    314                     handler.sendMessage(msg2);                
    315                 }
    316 
    317             }
    318         }
    319     }
    320 }
    321 
    322 附注:
    323 上面四个例子的布局文件是同一个文件main.xml
    324 
    325 <?xml version="1.0" encoding="utf-8"?>
    326 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    327     android:rientation="vertical"
    328     android:layout_width="fill_parent"
    329     android:layout_height="fill_parent"
    330     >
    331 <TextView  android:id="@+id/view_01"
    332     android:layout_width="fill_parent" 
    333     android:layout_height="wrap_content" 
    334     android:text="@string/hello"
    335     />
    336     
    337 <Button android:id="@+id/btn_01" 
    338     android:layout_width="fill_parent" 
    339     android:layout_height="wrap_content" 
    340     android:text="测试消息" />
    341 </LinearLayout>

    ==================================================================================================

    提供几个链接

    http://blog.csdn.net/mylzc/article/details/6771331

    http://tanghaibo001.blog.163.com/blog/static/9068612020111287218197/

    http://www.cnblogs.com/angeldevil/p/3340644.html

    http://www.cnblogs.com/xirihanlin/archive/2011/04/11/2012746.html

    http://www.cnblogs.com/angeldevil/p/3340644.html

    //个人理解:

    引用上面四组代码的例子(final 中的1---321行) 

    一个线程有一个Looper 管理一个messageQueue 主线程(ui线程的Looper 和messagequeue自动创建 其他线程需要静态方法prepare (Looper)  Looper 创建messageQueue也创建,)

    messageQueue存贮message

    异步处理实际上是不同线程对其他线程handler的操作 ,然后handler负责把生成的message发给自己的messagequeue中,而Looper则负责“常去看看queue里有没有新消息,要是有就获得消息”

    <我在回去看看代码理解理解这样理解对不对>

    //最终版本 

    接收发送消息<或者说对messagequeue的操作>全都是属于某一个Looper的一个handler所做的,异步处理实现的关键在于其他线程对handler的调用,严格的说是发送的调用

    线程A向线程B发送消息:

    线程A调用线程B的handler obtain一个message

    然后sendmessage

    此时在线程B的messagequeue中就出现新的message了,

    通过Looper的监听发现新的message后对这个message做相应的操作

    这样就完成了异步处理

  • 相关阅读:
    JavaScript基础知识——异步和单线程
    JavaScript基础知识——作用域和闭包
    JavaScript基础知识——原型和原型链
    JavaScript基础知识——变量类型与计算
    JavaScript 学者必看“new”
    Javascript中颇受诟病的「this错乱」问题
    Python之路
    Python
    Python
    python所遇问题合集(持续更新)
  • 原文地址:https://www.cnblogs.com/fuzhongqing/p/3780597.html
Copyright © 2020-2023  润新知