说到IntentService,其实他内部也是一个Thread + Handler实现的,之前我们在阅读源码,让你彻底理解AsyncTask运行原理这篇中我们就说过,他的原型其实也是Thread+Handler,对吧。只不过这个Thread有点特别,怎么个特别法呢?这个线程run()方法执行是获取创建Looper的操作,而平常呢,我们看看线程run()方法里,一般是执行一些耗时操作的对吧,比如我Asynbctask里面就是这样的。好了,不多说,下面我们来阅读阅读IntentService的源码。
IntentService是一种特殊的Service,他继承了Service,而且它还是一个抽象类,因此,你作为一个开发者,就必须是他的子类才能使用它,顺便还说一句,有的面试官会问你,抽象类能不能继承非抽象类,那么你看了IntentService这个类,那你的回答又会是什么呢?哈哈!答案显而易见,是可以的,对不?IntentService可用于执行后台的耗时操作,而且当他执行完相关的任务时,他就会停止自己,这也是Google官方给出优化应用内存中的一种方法。这个道理也很明显,当你不需要一个常驻后,让他执行完他的任务之后,就释放内存,节省内存开销,这对一个开发者来说,是一个良好的习惯。好,我们先来看看IntentService中的onCreate()方法:
@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(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
/**
* You should not override this method for your IntentService. Instead,
* override {@link #onHandleIntent}, which the system calls when the IntentService
* receives a start request.
* @see android.app.Service#onStartCommand
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
从上面代码可以看出,IntentService仅仅是通过mService发出一个消息,这个消息会在ServiceHandler中处理,mServiceHandler收到消息后,它会把这个Intent对象传递给onHandleIntent()方法去处理。注意,这里这个Intent对象跟你外部传来的Intent对象完全一致,通过这个Intent对象就可以解析在外部启动IntentService所传过来的相关参数,然后你通过这些参数就能区分具体的后台任务,这样在onHandleIntent()方法中就可以对不同的后台人物做处理了。当onHandleIntent()方法执行完之后,它就会调用stopSelf(int startId)方法来停止掉服务,那么这里采用stoptSelf(int startId)而不采用stopSelf()方法,那是因为,stopSelf()方法会立刻将服务停止掉,假如说某个时候,还有消息未处理,那怎么办?如果你调用stopSelf()方法的话,那么后面的消息,你将无法处理,这样,对我们来说是我们不想要的,而onStopSelf(int startId)就能帮我们解决这个问题,这个方法呢,会等待所有的消息处理完,才会将服务停止掉。
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 class MyIntentService extends IntentService {
private static final String TAG = "MyIntentService";
public MyIntentService(){
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
String action = intent.getStringExtra("task_action");
Log.e(TAG, "receive task" + action);
SystemClock.sleep(5000);
if("com.qhb.action.TASK1".equals(action)){
Log.e(TAG,"handle task : "+action);
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG,"service destroyed");
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(this,MyIntentService.class);
intent.putExtra("task_action", "com.qhb.action.TASK1");
startService(intent);
intent.putExtra("task_action","com.qhb.action.TASK2");
startService(intent);
intent.putExtra("task_action","com.qhb.action.TASK3");
startService(intent);
intent.putExtra("task_action", "com.qhb.action.TASK4");
startService(intent);
}
}
这里顺便说一下,Service与IntentService的区别就是能否执行耗时操作而已。
欢迎大家拍砖、吐槽。