Android消息驱动机制Handler+Looper+Thread+MessageQueue

1. 简介

    虽然对Android系统的整体了解不少,但对经常遇到的Android消息机制的实现并没有进行深入了解,趁现在有时间,顺便看一下,做总结一下。

2. 整体架构

    看了代码之后,觉得它一点都不神秘,不就是实现了我们常用的“消息驱动机制”吗?

    消息驱动机制的四要素:

    1) 接收消息的“消息队列

    2) 阻塞式地从消息队列中接收消息并进行处理的“线程

    3) 可发送的“消息的格式

    4) “消息发送函数”   

    以上四要素在Android中实现对应的类如下:

    1) 接收消息的“消息队列” ——【MessageQueue】

    2) 阻塞式地从消息队列中接收消息并进行处理的“线程” ——【Thread+Looper】

    3) 可发送的“消息的格式” ——【Message<Runnable被封装在Message中>】

    4) “消息发送函数”——【Handler的post和sendMessage】

   Android的消息驱动机制整体框架如下图所示:


 

3. 类的家族图谱

 


4.常用代码片断

4.1 Looper和Handler创建三步曲

      Handler只能处理由自己发出的Message

      Handler可以在任意线程中发送Message或Runnable;

      Haneler只能在与它绑定的Looper线程中处理消息。

      使用Handler可以解决在非主线程不能更新UI的问题(也可以通过SufaceView在非主线程更新UI),主线程也是一个Looper线程,代码详见ActivityThread.main函数,可以通过Looper.getMainLooper获取主线程的Looper, 然后创建与之绑定的Handler (new Handler(sMainLooper))。


[java]  view plain copy
  1. class LooperThread extends Thread {  
  2.     public Handler mHandler;  
  3.   
  4.     public void run() {  
  5.         Looper.prepare(); // 创建Looper并与本线程绑定  【第一步】  
  6.   
  7.         mHandler = new Handler() {  
  8.             // 定义并实现Handler.handleMessage方法     【第二步】  
  9.             public void handleMessage(Message msg) {  
  10.                 // process incoming messages here  
  11.             }  
  12.         };  
  13.           
  14.         Looper.loop(); // 启动Looper消息循环           【第三步】  
  15.     }  
  16. }  

4.2 Runnable定义及实现

[java]  view plain copy
  1. private final Runnable myRunnable= new Runnable() {  
  2.     public void run() {  
  3.         // 执行需要做的操作  
  4.     }  
  5. };  

5. 实例

[java]  view plain copy
  1. package com.example.mymsgdrv;  
  2.   
  3. import android.os.Bundle;  
  4. import android.os.Handler;  
  5. import android.os.Message;  
  6. import android.app.Activity;  
  7. import android.util.Log;  
  8. import android.view.Menu;  
  9. import android.widget.TextView;  
  10.   
  11. public class MainActivity extends Activity {  
  12.     public final String TAG = "MyMsgDrv";  
  13.     private TextView textView;  
  14.     private Handler myHandler;  
  15.     private MyThread myThread;  
  16.   
  17.     @Override  
  18.     protected void onCreate(Bundle savedInstanceState) {  
  19.         super.onCreate(savedInstanceState);  
  20.         setContentView(R.layout.activity_main);  
  21.         textView = (TextView)findViewById(R.id.textView2);  
  22.         textView.setText("Hello, This is only for test");  
  23.           
  24.         myHandler = new MyHandler();  
  25.         myThread = new MyThread(myHandler);  
  26.         myThread.start();  
  27.     }  
  28.   
  29.     @Override  
  30.     public boolean onCreateOptionsMenu(Menu menu) {  
  31.         // Inflate the menu; this adds items to the action bar if it is present.  
  32.         getMenuInflater().inflate(R.menu.main, menu);  
  33.         return true;  
  34.     }  
  35.   
  36.     class MyHandler extends Handler {  
  37.         @Override  
  38.         public void handleMessage(Message msg) {  
  39.             String str = msg.getData().getString("message");  
  40.             textView.setText(str);  
  41.         }  
  42.     }     
  43.       
  44.       
  45.     public class MyThread extends Thread{  
  46.         private Handler mHandler;  
  47.         MyThread(Handler handler){  
  48.             super();  
  49.             mHandler = handler;  
  50.         }  
  51.           
  52.         @Override  
  53.         public void run() {  
  54.             try {    
  55.                 int value=1;  
  56.                 while(value<20){  
  57.                     value++;  
  58.                     Thread.sleep(1000); // sleep 1s  
  59.                     // Message由Handler.handleMessage处理  
  60.                     Message msg = createMessage(mHandler,String.format("MyThread Send:%d",value));  
  61.                     mHandler.sendMessage(msg);  
  62.                 }  
  63.                   
  64.                 // Runnable在Handler中直接被调用执行  
  65.                 mHandler.postDelayed(myRunnable, 2000);  
  66.                   
  67.             } catch (InterruptedException e) {  
  68.                 Log.d(TAG, "interrupted!");  
  69.             }  
  70.         }  
  71.           
  72.         private Message createMessage(Handler handler,String str) {  
  73.             Message msg = handler.obtainMessage();  
  74.             Bundle data = new Bundle();  
  75.             data.putString("message", str);  
  76.             msg.setData(data);  
  77.             return msg;  
  78.         }   
  79.           
  80.         public Runnable myRunnable = new Runnable(){  
  81.             public void run(){  
  82.                 textView.setText("myRunnable is running now!");  
  83.             }  
  84.         };        
  85.     }  
  86. }  
  • 0
    点赞
  • 0
    收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值