为了引出HandlerThread类,我们现在先看看这样一个例子来说明Handler类和Looper类的同步关系:下面这段代码和例子出之《深入理解Android卷I》。
前面不是说到过,使用Handler来处理消息有助与分担主线程的工作,将与UI主线程无关且耗时的工作放到单独的工作线程中去,那么我们看看下面这样一个需求假设线程1是UI主线程,线程2是工作线程
class LooperThread extends Thread{ public Looper myLooper = null; public void run(){//假设run在线程2中执行 Looper.perpare(); //myLooper必须在这个线程中赋值 myLooper = Looper.myLooper(); Looper.loope(); } } //下面这段代码在线程1中执行,并且会创建线程2 { LooperThread lpThread=new LooperThread; lpThread.start();//start后会创建线程2 Looper looper = lpThread.myLooper;//-----注意----- //thread2Handler和线程2的Looper挂上钩 Handler thread2Handler = new Handler(looper); //发送消息将有线程2来处理 thread2Handler.sendMessage(。。。) }上面这段代码的目的在于,在线程一中创建线程2,并且线程1中得到线程2中创建的Looper对象,并且用这个线程2中创建的Looper对象来实例化一个Handler类 thread2Handler,那么通过这个 thread2Handler发送出去的消息都会在线程2中得到处理。
在看看下面这两行代码的差别:
Handler thread2Handler = new Handler(looper) //不能替换成 Handler thread2Handler = new Handler(Looper.myLooper())因为Looper.myLooper()函数返回的是当前线程(调用线程)的Looper,即如果使用第二种写法,那么不能像我们想的那样将线程2的looper传递给线程1。
为了解决上面的问题,我们引入了HandlerThread类。
下面我看看HandlerThread的内部接口
public class HandlerThread extends Thread { private int mPriority; private int mTid = -1; private Looper mLooper; public HandlerThread(String name) { super(name); mPriority = Process.THREAD_PRIORITY_DEFAULT; } /** * Constructs a HandlerThread. * @param name * @param priority The priority to run the thread at. The value supplied must be from * {@link android.os.Process} and not from java.lang.Thread. */ public HandlerThread(String name, int priority) { super(name); mPriority = priority; } ... public void run() { mTid = Process.myTid(); Looper.prepare(); synchronized (this) { mLooper = Looper.myLooper(); notifyAll(); } Process.setThreadPriority(mPriority); onLooperPrepared(); Looper.loop(); mTid = -1; } /** * This method returns the Looper associated with this thread. If this thread not been started * or for any reason is isAlive() returns false, this method will return null. If this thread * has been started, this method will block until the looper has been initialized. * @return The looper. */ public Looper getLooper() { 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(); } catch (InterruptedException e) { } } } return mLooper; } /*下面的代码来之WifiService.java*/ HandlerThread wifiThread = new HandlerThread("WifiService"); wifiThread.start(); mWifiHandler = new WifiHandler(wifiThread.getLooper());
假设在线程1中通过wifiThread.start()来开启线程2,线程1希望把对消息的处理函数放到线程2中去,在线程2开启的时候会运行run()函数,假设此时线程1从新获得CPU继续执行,进入到函数wifiThread.getLooper()中。那么如何保证线程1和线程2在Looper变量的传递上保持同步呢?HandlerThread中使用了一个java中的wait/notify机制,不懂的同学可以google下。在run()中如果mLooper变量实例化完成过后会notify来通知要取mLooper的线程1,同样在线程1中,如果getLooper()时还没有得到mLooper,则wait()等待唤醒。
其实Android中光一个Looper Handler就够我们学的了,只是菜鸟不才,目前只能把自己大概知道的记录在这里,Ok诸位晚安,如果哪位大牛发现这篇blog有什么错误,敬请指教,免得误导了其他菜鸟....