在上一篇我们分析了Handler的消息处理机制,我们也实现了在子线程中创建Handler对象,并且利用该Handler对象来处理了子线程自己发给自己的消息,但是要想让子线程中的Handler发挥作用,必须采用Looper.prepare( )来创建一个Looper对象,进而创建一个MessageQueue消息队列出来,随后调用Looper.loop( )方法来让消息队列运转起来;
我们来回顾下上一篇的实例:
public class MainActivity extends Activity { public Handler mHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); new Thread(new Runnable() { @Override public void run() { Looper.prepare(); Handler handler = new Handler(){ public void handleMessage(Message msg) { switch (msg.what) { case 0: System.out.println("message.what == 0"); break; case 1: System.out.println("message.what == 1"); break; default: break; } }; }; handler.sendEmptyMessage(0); Looper.loop(); } }).start(); } }
输出结果:message.what == 0
但是你不觉得很麻烦么?我们每次都要添加Looper.prepare( )和Looper.loop( )方法,这一点android已经为我们考虑到啦,就是HandlerThread;
我们先来看看HandlerThread的一个实例:
public class MainActivity extends Activity { public Handler mHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); HandlerThread thread = new HandlerThread("huzhiwei"); thread.start(); Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { switch (msg.what) { case 0: System.out.println("message.what == 0"); break; case 1: System.out.println("message.what == 1"); break; default: break; } } }; handler.sendEmptyMessage(0); } }
输出结果:message.what == 0
解释:(1)首先通过构造函数生成一个HandlerThread对象,参数是用于调试用的,具体没多大用途
(2)调用start方法开启线程
(3)生成一个Handler对象,并重写里面的handleMessage方法
这下子你可能就会疑问为什么HandlerThread里面没有执行Looper.prepare()和Looper.loop()方法就能进行接收和处理消息呢?别急,其实是HandlerThread帮你封装了而已的,看看HandlerThread的源码就知道啦
class HandlerThread extends Thread { int mPriority;//线程优先级 int mTid = -1;//线程ID Looper mLooper;//Looper对象 public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT;//如果创建HandlerThread的时候没有线程优先级传入,则定义为默认优先级 } public HandlerThread(String name, int priority) { super(name); mPriority = priority;//设置线程优先级 } //这是监听方法,我们在创建HandlerThread的时候可以重写该方法,该方法会在run方法里面调用 protected void onLooperPrepared() { } @Override public void run() { mTid = Process.myTid();//获取线程ID Looper.prepare();//生成Looper对象,同时创建MessageQueue消息队列,并且将Looper加入到ThreadLocal中 synchronized (this) { mLooper = Looper.myLooper();//从ThreadLocal中获得Looper对象 notifyAll(); } Process.setThreadPriority(mPriority);//设置线程的优先级 onLooperPrepared();//调用我们自己实现的回调方法 Looper.loop();//开始消息处理 mTid = -1;//将当前线程设置为invalid } public Looper getLooper() { //如果当前线程不在ALIVE状态的话,直接返回null,说明我们没有执行start()方法 if (!isAlive()) { return null; } // If the thread has been started, wait until the looper has been created. synchronized (this) { while (isAlive() && mLooper == null) { try { wait();//一直等待,直到mLooper不为null } catch (InterruptedException e) { } } } return mLooper; } public boolean quit() { Looper looper = getLooper();//获得当前的Looper对象 if (looper != null) { looper.quit();//退出 return true; } return false; } }源码看注释就可以看懂了吧,这里有一个问题需要说明一下,在run方法里面有一个notifyAll()方法,getLooper方法里面有个wait()方法,这两个方法是相互匹配的,我们只有在run方法中创建了Looper对象才能在getLooper方法里面获取到该对象,如果run方法未创建的话,getLooper会执行wait方法一直等待, notifyAll会将原来在该对象上处于wait状态的线程全部结束其wait状态,因此wait和notifyAll是用来对生成Looper对象进行同步操作的;