转载

结合源代码详解android消息模型

Handler是整个消息系统的核心,是Handler向MessageQueue发送的Message,最后Looper也是把消息通知给Handler,所以就从Handler讲起。

一、Handler

Handler的构造函数有很多,但本质差不多:

public Handler() {           this(null, false);       }
public Handler(Callback callback, boolean async) {    //自动绑定当前线程的looper    mLooper = Looper.myLooper();    if (mLooper == null) {     throw new RuntimeException(      "Can't create handler inside thread that has not called Looper.prepare()");//从这可以看出,创建Handler必须有Looper    }    mQueue = mLooper.mQueue;  //Looper的MessageQueue    mCallback = callback;  //一个回掉接口    mAsynchronous = async;  } 

这个是创建给定Looper的Handler  :

public Handler(Looper looper, Callback callback, boolean async) {            mLooper = looper;          mQueue = looper.mQueue;          mCallback = callback;          mAsynchronous = async;      }

二、Looper的源代码:

public static Looper myLooper() {          return sThreadLocal.get();      }

在一个子线程中创建Looper的一般步骤:(这是我自己写的,不是源代码)

class MyThread extends Thread{    public Handler handler;    public Looper looper;    public void run() {     Looper.prepare();//创建一个looper     looper = Looper.myLooper();     handler = new Handler(){        @Override     public void handleMessage(Message msg) {        System.out.println("currentThread->"+Thread.currentThread());        }       };       Looper.loop();//让消息循环起来    }   } 

下面就看看Looper.prepare,Looper.loop方法:

public static void prepare() {    prepare(true);   }   private static void prepare(boolean quitAllowed) {    if (sThreadLocal.get() != null) {//sThreadLocal使得线程能够保持各自独立的一个对象。     throw new RuntimeException("Only one Looper may be created per thread");    }    sThreadLocal.set(new Looper(quitAllowed));   } 

Looper.prepare():

public static void loop() {    final Looper me = myLooper();    if (me == null) { //如果Looper为空     throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");    }    final MessageQueue queue = me.mQueue;    。。。。    for (;;) {     Message msg = queue.next(); // 循环下一个     if (msg == null) {      // No message indicates that the message queue is quitting.      return;     }       。。。。     msg.target.dispatchMessage(msg);  //分发消息,msg.target就是Handler     if (logging != null) {      logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);     }     。。。。     msg.recycle();  //回收msg到msgPool    }   } 

从这些代码可以看出Looper不断检查MessagePool是否有《==Message,有的话就通过Handler的dispatchMessage(msg)发送出去,利用Handler与外界交互。

3.Message的源代码:

public static Message obtain() {   //得到Message对象    synchronized (sPoolSync) {     if (sPool != null) {      Message m = sPool;      sPool = m.next;      m.next = null;      sPoolSize--;      return m;     }    }    return new Message();  //没有就新建   } 

handler.obtainMessage()方法:

public final Message obtainMessage()      {          return Message.obtain(this);  //通过Message的obtain方法      }
public static Message obtain(Handler h) {  //就是这个方法         Message m = obtain();  //最终调用的还是obtain方法         m.target = h;      //target是handler            return m;     }

看了上边的源代码,相信你一定对Handler,message,Looper有了一定了解,对编程中常遇到的方法,知道是怎么用的啦。其实学android一定要常看源码,源码很有用。

4.下边就是上代码,实例分析:

<pre name="code" class="java">package com.example.handler_01;      import android.Manifest.permission;   import android.app.Activity;   import android.os.Bundle;   import android.os.Handler;   import android.os.Handler.Callback;   import android.os.Message;   import android.view.Menu;   import android.view.MenuItem;   import android.view.View;   import android.view.View.OnClickListener;   import android.widget.Button;   import android.widget.ImageView;   import android.widget.TextView;   import android.widget.Toast;      public class MainActivity extends Activity implements OnClickListener{          private TextView textView;       private Button button;                     private Handler handler = new Handler(new Callback() {//拦截消息                      public boolean handleMessage(Message msg) {  //截获handler的发送的消息                          Toast.makeText(getApplicationContext(), ""+1, 1).show();               //return false;               return false;//若返回true,则证明截获,下面的handleMessage就不会执行!           }       }){           public void handleMessage(Message msg) {               Toast.makeText(getApplicationContext(), ""+2, 1).show();               Person person = (Person)msg.obj;               System.out.println(person.toString());           }       };              private MyRunnable myRunnable=new MyRunnable();              private ImageView imageView;              private int images[]={R.drawable.a1,R.drawable.a2,R.drawable.a3};       private int index;              class MyRunnable implements Runnable{  //不断的更新图片,3张轮换              @Override           public void run() {             index++;             index=index%3;  //不断循环             imageView.setImageResource(images[index]);             handler.postDelayed(myRunnable, 1000);  //每隔一段时间执行myRunnable             System.out.println("MyRunnable中的线程:"+Thread.currentThread());//运行在当前主线程!           }                  }       @Override       protected void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);           setContentView(R.layout.activity_main);           textView = (TextView) findViewById(R.id.textview);           imageView = (ImageView) findViewById(R.id.imageView1);           button = (Button) findViewById(R.id.button1);           button.setOnClickListener(this);           new Thread(){               @Override               public void run() {                   try {                       Thread.sleep(2000);                       /*Message message = new Message();                     message.arg1=88;*/                      Message message = handler.obtainMessage();                                             Person person = new Person();                      person.age=20;                      person.name="chaochao";                      message.obj=person;                      handler.sendMessage(message);//在子线程中向主线程发消息。                   } catch (InterruptedException e) {                       // TODO Auto-generated catch block                       e.printStackTrace();                   }                                  }           }.start();           handler.postDelayed(myRunnable, 1000);       }       @Override       public void onClick(View v) {           switch (v.getId()) {           case R.id.button1:               handler.removeCallbacks(myRunnable);               //handler.sendEmptyMessage(1);               break;              default:               break;           }                  }          class Person{           public int age;           public String name;                      public String toString() {             return "name="+name+" age="+age;           }       }   }

布局很简单,就不上代码啦。

运行结果:

结合源代码详解android消息模型

图片自己可以随便能一个。。。。

在后边再详细解析Handler的用法。。

转发请注明出处:http://www.cnblogs.com/jycboy/p/handlerjx.html

正文到此结束
Loading...