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

来源:互联网 发布:硅藻泥脚垫 知乎 编辑:程序博客网 时间:2024/06/05 03:47

Handler是整个消息系统的核心,是Handler向MessageQueue发送的Message,最后Looper也是把消息通知给1.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;    }
2.在看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张轮换@Overridepublic void run() {          index++;          index=index%3;  //不断循环          imageView.setImageResource(images[index]);          handler.postDelayed(myRunnable, 1000);  //每隔一段时间执行myRunnable          System.out.println("MyRunnable中的线程:"+Thread.currentThread());//运行在当前主线程!}}@Overrideprotected 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(){@Overridepublic 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 blocke.printStackTrace();}}}.start();handler.postDelayed(myRunnable, 1000);}@Overridepublic 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;}}}
布局很简单,就不上代码啦。
</pre><p></p><pre>

运行结果:



这次代码先写到这,饿啦去吃饭,在后边再详细解析Handler的用法。。

转载请注明出处:http://blog.csdn.net/jycboy/article/details/46445677





0 0
原创粉丝点击