Android HandlerThread和IntentService
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)