zoukankan      html  css  js  c++  java
  • android消息处理机制之2handler与looper,MessageQueue:的关系

    // 

    Looper

      在UI主线程里面有默认有一个Looper对象来管理UI线程的各条消息,但是在自定义的实现Thread的消息循环和消息派发,缺省情况下Thread是没有这个消息循环的既没有Looper;需要主动去创建将该线程内部的message添加到messagequeue中去,让looper来进行管理添加到,然后启动Looper的消息循环loop;与外部的交互通过Handler进行;

    MessageQueue

      消息队列,由Looper所持有,但是消息的添加是通过Handler进行;

      消息循环和消息队列都是属于Thread,而Handler本身并不具有Looper和MessageQueue;

    但是消息系统的建立和交互,是Thread将Looper和MessageQueue交给某个Handler维护建立消息系统模型。所以消息系统模型的核心就是Looper。消息循环和消息队列都是由Looper建立的,而建立Handler的关键就是这个Looper。

      一个Thread同时可以对应多个Handler,一个Handler同时只能属于一个Thread。Handler属于哪个

    Thread取决于Handler在那个Thread中建立。

      在一个Thread中Looper也是唯一的,一个Thread对应一个Looper,建立Handler的Looper来自哪个Thread,

    Handler属于哪个Thread。

    //================首先是让handler有一个需要looper对象的构造来看一下,在主线程里面是不是有一个looper对象。

     1  2 
     3 import android.os.Bundle;
     4 import android.os.Handler;
     5 import android.os.Looper;
     6 import android.os.Message;
     7 import android.view.View;
     8 import android.widget.Button;
     9 import android.widget.TextView;
    10 import android.app.Activity;
    11 
    12 public class Main extends Activity {
    13     private Button button;
    14     private TextView textView;
    15     private MyHandler handler;
    16 
    17     @Override
    18     protected void onCreate(Bundle savedInstanceState) {
    19         super.onCreate(savedInstanceState);
    20         setContentView(R.layout.main);
    21         // 在activity里面有一个默认的Looper对象来处理子线程中发送的消息。
    22         button = (Button) findViewById(R.id.button1);
    23         textView = (TextView) findViewById(R.id.editText1);
    24         // 获取looper
    25         Looper looper = Looper.getMainLooper();  //
    26         handler = new MyHandler(looper);   //通过这个looper传递过去
    27         handler = new MyHandler();  ///这个效果和上面的效果执行上是一模一样的。
    28         button.setOnClickListener(new View.OnClickListener() {
    29             @Override
    30             public void onClick(View v) {
    31                 // TODO Auto-generated method stub
    32                 new Thread(new MyThread()).start();
    33             }
    34         });
    35     }
    36 
    37     // 子线程
    38     public class MyThread implements Runnable {
    39         @Override
    40         public void run() {
    41             // TODO Auto-generated method stub
    42             Message message = Message.obtain();
    43             message.obj = "LooperMessage";
    44             handler.sendMessage(message);
    45         }
    46     }
    47 
    48     // 继承一个handler类
    49     public class MyHandler extends Handler {
    50         public MyHandler() {
    51             // TODO Auto-generated constructor stub
    52         }
    53 
    54         // 定义一个带参构造方法
    55         public MyHandler(Looper looper) {
    56             super(looper);
    57         }
    58 
    59         @Override
    60         public void handleMessage(Message msg) {
    61             // TODO Auto-generated method stub
    62             super.handleMessage(msg);
    63             textView.setText("-接收消息-->" + msg.obj.toString());
    64         }
    65     }
    66 
    67 }

    //  验证只有加入到messageQueue的消息队列里面handler才可以获取,处理,分发。而这个messageQueue就是有looper进行管理的。

    //这个是从UI主线想子线程中发送消息,只要将将要发送的消息加入到looper管理的messageQueue(主线程)队列中去,在同一个消息队列里面处理一个消息不就很easy吗?

     1 package com.example.handler_looper_01;
     2 
     3 import android.os.Bundle;
     4 import android.os.Handler;
     5 import android.os.Looper;
     6 import android.os.Message;
     7 import android.view.View;
     8 import android.widget.Button;
     9 import android.widget.TextView;
    10 import android.app.Activity;
    11 
    12 /**
    13  * 将消息从UI主线程中发送到子线程中,比较少用~~
    14  * 
    15  * @author lpp
    16  * 
    17  */
    18 public class Main extends Activity {
    19     private Button button;
    20     private TextView textView;
    21     private Handler handler; // 获取handler对象
    22 
    23     @Override
    24     protected void onCreate(Bundle savedInstanceState) {
    25         super.onCreate(savedInstanceState);
    26         setContentView(R.layout.main);
    27         // 在activity里面有一个默认的Looper对象来处理子线程中发送的消息。
    28         button = (Button) findViewById(R.id.button1);
    29         textView = (TextView) findViewById(R.id.editText1);
    30         // 启动线程
    31         new Thread(new MyThread()).start();
    32         button.setOnClickListener(new View.OnClickListener() {
    33             @Override
    34             public void onClick(View v) {
    35                 Message message = Message.obtain();
    36                 message.obj = "UI的message";
    37                 handler.sendMessage(message);
    38             }
    39         });
    40     }
    41 
    42     // 子线程
    43     public class MyThread implements Runnable {
    44         @Override
    45         public void run() {
    46             // 在线程里面与activity不一样是没有looper与之进行关联。因此是无法接收到looper里面的消息!直接报错
    47             Looper.prepare(); // 循环消息队列
    48             // 接受Ui主线程发送过来的消息
    49             handler = new Handler() {
    50                 @Override
    51                 public void handleMessage(Message msg) {
    52                     super.handleMessage(msg);
    53                     // CalledFromWrongThreadException: Only the original thread
    54                     // that created a view hierarchy can touch its views.
    55                     // textView.setText(msg.obj.toString()); //
    56                     // 这属于在子线程中更新UI,会直接报错!
    57                     System.out.println(msg.obj.toString());
    58 
    59                 }
    60             };
    61             Looper.loop(); // 知道消息队列循环结束
    62         }
    63     }
    64 }

    消息循环和消息队列都是属于Thread,而Handler本身并不具有Looper和MessageQueue;

    但是消息系统的建立和交互,是Thread将Looper和MessageQueue交给某个Handler维护建立消息系统模型。

      所以消息系统模型的核心就是Looper。消息循环和消息队列都是由Looper建立的,

    而建立Handler的关键就是这个Looper。

      一个Thread同时可以对应多个Handler,一个Handler同时只能属于一个Thread。Handler属于哪个

    Thread取决于Handler在那个Thread中建立。

      在一个Thread中Looper也是唯一的,一个Thread对应一个Looper,建立Handler的Looper来自哪个Thread,

    Handler属于哪个Thread。

  • 相关阅读:
    Qt之镜像旋转
    Qt之QCheckBox
    Qt之动画框架
    Qt之QFileSystemWatcher
    Qt之qSetMessagePattern
    Qt之qInstallMessageHandler(重定向至文件)
    Qt之qInstallMessageHandler(输出详细日志)
    Qt之窗体透明
    Qt之窗体拖拽、自适应分辨率、自适应大小
    Qt之设置应用程序图标
  • 原文地址:https://www.cnblogs.com/fuck1/p/5513478.html
Copyright © 2011-2022 走看看