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

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张轮换

		@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;
		}
	}
}
布局很简单,就不上代码啦。
</pre><p></p><pre>

运行结果:



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

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


 



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值