Android中的Thread沒有對java中的Thread作任何封裝,而Android提供了一個遍歷方法HandlerThread,他繼承於Thread,實現了對遍歷系統的一些封裝,下面研究一下HandlerThread的源碼:java
1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.os; 18 19 /** 20 * Handy class for starting a new thread that has a looper. The looper can then be 21 * used to create handler classes. Note that start() must still be called. 22 */ 23 public class HandlerThread extends Thread { 24 int mPriority; 25 int mTid = -1; 26 Looper mLooper; 27 28 public HandlerThread(String name) { 29 super(name); 30 mPriority = Process.THREAD_PRIORITY_DEFAULT; 31 } 32 33 /** 34 * Constructs a HandlerThread. 35 * @param name 36 * @param priority The priority to run the thread at. The value supplied must be from 37 * {@link android.os.Process} and not from java.lang.Thread. 38 */ 39 public HandlerThread(String name, int priority) { 40 super(name); 41 mPriority = priority; 42 } 43 44 /** 45 * Call back method that can be explicitly overridden if needed to execute some 46 * setup before Looper loops. 47 */ 48 protected void onLooperPrepared() { 49 } 50 51 @Override 52 public void run() { 53 mTid = Process.myTid(); 54 Looper.prepare(); 55 synchronized (this) { 56 mLooper = Looper.myLooper(); 57 notifyAll(); 58 } 59 Process.setThreadPriority(mPriority); 60 onLooperPrepared(); 61 Looper.loop(); 62 mTid = -1; 63 } 64 65 /** 66 * This method returns the Looper associated with this thread. If this thread not been started 67 * or for any reason is isAlive() returns false, this method will return null. If this thread 68 * has been started, this method will block until the looper has been initialized. 69 * @return The looper. 70 */ 71 public Looper getLooper() { 72 if (!isAlive()) { 73 return null; 74 } 75 76 // If the thread has been started, wait until the looper has been created. 77 synchronized (this) { 78 while (isAlive() && mLooper == null) { 79 try { 80 wait(); 81 } catch (InterruptedException e) { 82 } 83 } 84 } 85 return mLooper; 86 } 87 88 /** 89 * Quits the handler thread's looper. 90 * <p> 91 * Causes the handler thread's looper to terminate without processing any 92 * more messages in the message queue. 93 * </p><p> 94 * Any attempt to post messages to the queue after the looper is asked to quit will fail. 95 * For example, the {@link Handler#sendMessage(Message)} method will return false. 96 * </p><p class="note"> 97 * Using this method may be unsafe because some messages may not be delivered 98 * before the looper terminates. Consider using {@link #quitSafely} instead to ensure 99 * that all pending work is completed in an orderly manner. 100 * </p> 101 * 102 * @return True if the looper looper has been asked to quit or false if the 103 * thread had not yet started running. 104 * 105 * @see #quitSafely 106 */ 107 public boolean quit() { 108 Looper looper = getLooper(); 109 if (looper != null) { 110 looper.quit(); 111 return true; 112 } 113 return false; 114 } 115 116 /** 117 * Quits the handler thread's looper safely. 118 * <p> 119 * Causes the handler thread's looper to terminate as soon as all remaining messages 120 * in the message queue that are already due to be delivered have been handled. 121 * Pending delayed messages with due times in the future will not be delivered. 122 * </p><p> 123 * Any attempt to post messages to the queue after the looper is asked to quit will fail. 124 * For example, the {@link Handler#sendMessage(Message)} method will return false. 125 * </p><p> 126 * If the thread has not been started or has finished (that is if 127 * {@link #getLooper} returns null), then false is returned. 128 * Otherwise the looper is asked to quit and true is returned. 129 * </p> 130 * 131 * @return True if the looper looper has been asked to quit or false if the 132 * thread had not yet started running. 133 */ 134 public boolean quitSafely() { 135 Looper looper = getLooper(); 136 if (looper != null) { 137 looper.quitSafely(); 138 return true; 139 } 140 return false; 141 } 142 143 /** 144 * Returns the identifier of this thread. See Process.myTid(). 145 */ 146 public int getThreadId() { 147 return mTid; 148 } 149 }
下面來分析一下該類的實現原理:android
一、首先該類有兩個構造方法:一個傳入一個字符串名稱,任意選取,優先級設置爲默認的,第二個多了設置進程優先級的參數express
二、apache
實際上簡單理解就是:HandlerThread可讓Handler運行於其餘線程中,在日常應用中,以Activity爲例,新建一個Handler對象,默認是運行於UI線程中的,若是須要在Handler中執行一些耗時的任務,能夠從新開啓一個子線程來執行,而不能夠直接在handler中執行;多線程
那具體用途在於哪呢?app
若是須要在子線程中使用Handler類,首先須要建立Looper類實例,這時能夠經過Looper.prepare()和Looper.loop()函數來實現的。閱讀Framework層源碼發現,Android爲咱們提供了一個HandlerThread類,該類繼承Thread類,並使用上面兩個函數建立Looper對象,並且使用wait/notifyAll解決了多線程中子線程1獲取子線程2的Looper對象爲空的問題less
爲了方便描述,這裏附上一段demo:ide
1 void useHanlerThread() { 2 3 // two ways to construct HandlerThread 4 HandlerThread hThread = new HandlerThread(」AnyName「, 5 6 // a property in android.os.Process 7 Process.THREAD_PRIORITY_BACKGROUND); 8 9 // HandlerThread hThread2 = new HandlerThread(」AnyName「); 10 hThread.start(); 11 12 // get Looper object of hThread(HandlerThread) 13 Looper looper = hThread.getLooper(); 14 15 Handler h = new Handler(looper) { 16 @Override 17 public void handleMessage(Message msg) { 18 // TODO Auto-generated method stub 19 super.handleMessage(msg); 20 } 21 }; 22 23 }
由上面代碼第4行能夠看到,這裏採用HandlerThread新建一個thread對象,實際上他就是一個Thread,只不過通過了一些封裝,它封裝了looper等,因此該實例也就是一個worker thread,也即新建了一個線程,只是不須要維護Looper,內部封裝好了,當調用HandlerThread的start方法時,就會執行重寫的run方法,進而能夠直接經過第13行代碼的getLooper獲取,而後根據獲取的這個looper來實例化Handler,這樣這個Handler就工做於前面建立的HandlerThread實例中,也就是說相比傳統的方式,這裏能夠直接處理耗時邏輯而無需再新建線程函數
這裏再附上一段樣例代碼來輔助理解:oop
1 public void startWorkerHandler(){ 2 HandlerThread handlerThread = new HandlerThread("handler-thread"); 3 handlerThread.start(); 4 5 final Handler handler = new Handler(handlerThread.getLooper()); 6 handler.post(new Runnable() { 7 @Override 8 public void run() { 9 10 npb.increaseProgressBy(1); 11 handler.postDelayed(this, 100); 12 } 13 }); 14 }
實例:
1 package com.example.randy.helloworld; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.os.Handler; 6 import android.os.HandlerThread; 7 import android.os.Looper; 8 9 /** 10 * Created by randy on 2015/12/7. 11 */ 12 public class HandlerDemo extends Activity { 13 private Handler handler1; 14 15 private Handler handler2; 16 17 private HandlerThread handlerThread; 18 private Handler handler3; 19 20 @Override 21 protected void onCreate(Bundle savedInstanceState) { 22 super.onCreate(savedInstanceState); 23 setContentView(R.layout.activity_main); 24 handler1 = new Handler(); 25 new Thread(new Runnable() { 26 @Override 27 public void run() { 28 Looper.prepare(); 29 handler2 = new Handler(); 30 Looper.loop(); 31 } 32 }).start(); 33 34 /* new Thread(new Runnable(){ 35 @Override 36 public void run(){ 37 handlerThread = new HandlerThread("handlerThread"); 38 handlerThread.start(); 39 } 40 }).start();*/ 41 42 new HandlerThread("handlerThread"){ 43 44 @Override 45 public void run(){ 46 47 handler3 = new Handler(); 48 } 49 }.start(); 50 } 51 }