IntentService 是一种特殊的 Service,它继承了 Service 并且它是一个抽象类,因此必须创建它的子类才能够使用 IntentService。它可用于执行后台耗时任务,当任务执行完成后它会自动停止,在资源不足时,系统会对一些被认为时无用的资源给清理掉,由于它是 Service 的原因,它的优先级比单纯的线程的优先级高很多,不容易被系统杀死(清理掉),所以它适合执行一些高优先级的后台任务。在实现上,IntentService 封装了 Handlerhread 和 Handler。
HandlerThread
继承了 Thread
,它是一种可以使用 Handler
的 Thread
。它的实现是通过在run()
方法中通过Looper.prepare()
来创建消息队列,并通过Looper.loop()
方法来开启消息循环, 它的内部对Thread 的 run 方法
进行重写,通过Handler
的消息方式(Looper循环)来通知HandlerThread
执行一个具体的任务。
@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}
在明确了不需要使用HandlerThread
的时,可以通过它的quit
或者quitSafely
方法来终止线程的执行
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;
}
这两个方法的区别是:
quit()
使用此方法可能是不安全的,因为在Looper
队列终止之前可能无法传递某些消息。
quitSafely()
使用此方法可能是安全的,因为一旦已经传递消息,队列中的所有剩余消息被处理,方法就会终止。然而,在循环终止之前,延迟的消息将在未来的到期时间内不传递。
onCreate()
初始化HandlerThread
和ServiceHandler
,用于在后面调用onStart
后来发送消息。@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);
}
onStartCommand()
方法,并且它会调用onStart()
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
onStart()
中发送消息@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
后台任务是顺序执行的
因为 Handler 中的 Looper 是顺序处理消息。
任务执行完成之后结束服务:
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); 而不使用 stopSelf();
// 是因为 stopSelf() 会立即停止服务,
// 而 stopSelf(msg.arg1); 在停止服务前会先判断最近启动服务的次数是否和 startId 相等
// 如果相等就历经停止服务,不想动则不停止服务
stopSelf(msg.arg1);
}
}
IntentService
public class TestIntentService extends IntentService {
private static final String TAG = "TestIntentService";
public TestIntentService() {
super(TAG);
Log.e(TAG, "TestIntentService: " );
}
@Override
public void onCreate() {
super.onCreate();
Log.e(TAG, "onCreate: " );
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
String taskAction = intent.getStringExtra("task_action");
SystemClock.sleep(3000);
Log.e(TAG, "onHandleIntent: "+taskAction);
}
@Override
public void onDestroy() {
Log.e(TAG, "onDestroy: service destory" );
super.onDestroy();
}
}
AndroidMainfest.xml
中注册服务<service android:name=".thread.TestIntentService"/>
Intent intent = new Intent(CallBackTestActivity.this, TestIntentService.class);
intent.putExtra("task_action","com.dx.action.TASK1");
// 开启第一个服务
startService(intent);
intent.putExtra("task_action","com.dx.action.TASK2");
// 开启第二个服务
startService(intent);
intent.putExtra("task_action","com.dx.action.TASK3");
// 开启第三个服务
startService(intent);
从截图中的时间,以及输出顺序正好验证了上面的叙述!
ok,完工~
致每个一直向前努力的人们!