HandlerThread
HandlerThread繼承了Thread,它是一種可以使用Handler的Thread,它實現也很簡單,就是在run中通過Looper.prepare()來創建消息隊列,並且通過Looper.loop()來開啓消息循環,這樣再實際使用中就允許在HandlerThread中創建Handle了。
public class HandlerThread extends Thread {
int mPriority;
int mTid = -1;
Looper mLooper;
private @Nullable Handler mHandler;
public HandlerThread(String name) {
super(name);
mPriority = Process.THREAD_PRIORITY_DEFAULT;
}
public HandlerThread(String name, int priority) {
super(name);
mPriority = priority;
}
protected void onLooperPrepared() {
}
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
public Looper getLooper() {
//Thread.IsAlive屬性 ,表示該線程當前是否爲可用狀態
//如果線程已經啓動,並且當前沒有任何異常的話,則是true,否則爲false
//Start()後,線程不一定能馬上啓動起來,也許CPU正在忙其他的事情,但遲早是會啓動起來的!
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;
}
@NonNull
public Handler getThreadHandler() {
if (mHandler == null) {
mHandler = new Handler(getLooper());
}
return mHandler;
}
public boolean quit() {
Looper looper = getLooper();
if (looper != null) {
looper.quit();
return true;
}
return false;
}
public boolean quitSafely() {
Looper looper = getLooper();
if (looper != null) {
looper.quitSafely();
return true;
}
return false;
}
public int getThreadId() {
return mTid;
}
}
IntentService
- IntentService是一種特殊的Service,它繼承了Service並且它是一個抽象類,因此必須創建它的子類才能使用IntentService
- IntentService可用於執行後臺耗時的任務,當任務執行後它會自動停止,同事由於IntentService是服務的原因,這導致它的優先級比單純的線程要高很多,所以IntentService比較適合執行一些高級優先級的後臺任務,因爲它的優先級高不容易被系統殺死。
- 在實現上,IntentService封裝了HandlerThread和Handler,這一點可以從它的onCreate方法中看出來。
public abstract class IntentService extends Service {
private volatile Looper mServiceLooper;
private volatile ServiceHandler mServiceHandler;
private String mName;
private boolean mRedelivery;
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
public IntentService(String name) {
super();
mName = name;
}
public void setIntentRedelivery(boolean enabled) {
mRedelivery = enabled;
}
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
@Override
public void onDestroy() {
mServiceLooper.quit();
}
@Override
@Nullable
public IBinder onBind(Intent intent) {
return null;
}
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);
}
使用:
class IntentServiceDemo : IntentService("IntentServiceDemo") {
private val TAG = "zmm"
/* (non-Javadoc)
* @see android.app.IntentService#onCreate()
*/
override fun onCreate() {
Log.e(TAG, "=>onCreate")
super.onCreate()
}
override fun onStartCommand(@Nullable intent: Intent?, flags: Int, startId: Int): Int {
Log.e(TAG, "=>onStartCommand")
return super.onStartCommand(intent, flags, startId)
}
/* (non-Javadoc)
* @see android.app.IntentService#onDestroy()
*/
override fun onDestroy() {
Log.e(TAG, "=>onDestroy")
super.onDestroy()
}
override fun onHandleIntent(arg0: Intent?) {
try {
Log.e(TAG, "IntentService 線程:" + Thread.currentThread().id)
Thread.sleep(2000)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}
var mServiceIntent = Intent(this@MainActivity, IntentServiceDemo::class.java)
startService(mServiceIntent)