标签:
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
标签:
原文地址:http://www.cnblogs.com/jycboy/p/handlerjx.html