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))。
- class LooperThread extends Thread {
- public Handler mHandler;
- public void run() {
- Looper.prepare(); // 创建Looper并与本线程绑定 【第一步】
- mHandler = new Handler() {
- // 定义并实现Handler.handleMessage方法 【第二步】
- public void handleMessage(Message msg) {
- // process incoming messages here
- }
- };
- Looper.loop(); // 启动Looper消息循环 【第三步】
- }
- }
4.2 Runnable定义及实现
- private final Runnable myRunnable= new Runnable() {
- public void run() {
- // 执行需要做的操作
- }
- };
5. 实例
- package com.example.mymsgdrv;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.app.Activity;
- import android.util.Log;
- import android.view.Menu;
- import android.widget.TextView;
- public class MainActivity extends Activity {
- public final String TAG = "MyMsgDrv";
- private TextView textView;
- private Handler myHandler;
- private MyThread myThread;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- textView = (TextView)findViewById(R.id.textView2);
- textView.setText("Hello, This is only for test");
- myHandler = new MyHandler();
- myThread = new MyThread(myHandler);
- myThread.start();
- }
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Inflate the menu; this adds items to the action bar if it is present.
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
- class MyHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- String str = msg.getData().getString("message");
- textView.setText(str);
- }
- }
- public class MyThread extends Thread{
- private Handler mHandler;
- MyThread(Handler handler){
- super();
- mHandler = handler;
- }
- @Override
- public void run() {
- try {
- int value=1;
- while(value<20){
- value++;
- Thread.sleep(1000); // sleep 1s
- // Message由Handler.handleMessage处理
- Message msg = createMessage(mHandler,String.format("MyThread Send:%d",value));
- mHandler.sendMessage(msg);
- }
- // Runnable在Handler中直接被调用执行
- mHandler.postDelayed(myRunnable, 2000);
- } catch (InterruptedException e) {
- Log.d(TAG, "interrupted!");
- }
- }
- private Message createMessage(Handler handler,String str) {
- Message msg = handler.obtainMessage();
- Bundle data = new Bundle();
- data.putString("message", str);
- msg.setData(data);
- return msg;
- }
- public Runnable myRunnable = new Runnable(){
- public void run(){
- textView.setText("myRunnable is running now!");
- }
- };
- }
- }