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)