结合源代码详解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;  
        }  
    }  
}  

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

运行结果:

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

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

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

posted @ 2015-09-03 12:14  超超boy  阅读(877)  评论(0编辑  收藏  举报