1、 简介
IntentService是Service的子类,根据需要处理异步请求(以intent表示)。客户端通过调用startService(Intent) 发送请求,该Service根据需要启动,使用工作线程处理依次每个Intent,并在停止工作时停止自身。
这种“工作队列处理器”模式通常用于从应用程序的主线程中卸载任务。 IntentService类的存在是为了简化这种模式。 要使用它,扩展IntentService并实现onHandleIntent(Intent)。 IntentService将收到Intents,启动一个工作线程,并根据需要停止该服务。
所有请求都在单个工作线程处理 - 它们可能需要很长的时间(并且不会阻止应用程序的主循环),但是一次只会处理一个请求。
2 、代码
在IntentService中处理下载请求(模拟),并将进度更新到Ui。
MyIntentService.java代码如下:
public class MyIntentService extends IntentService {
private final static String TAG = "MyIntentService";
public static final String ACTION_DOWN_IMG = "down.image";
public static final String ACTION_DOWN_VID = "down.vid";
public static final String ACTION_DOWN_PROGRESS = "com.zpengyong.down.progress";
public static final String ACTION_SERVICE_STATE = "com.zpengyong.service.state";
public static final String PROGRESS = "progress";
public static final String SERVICE_STATE = "service_state";
//构造方法 一定要实现此方法否则Service运行出错。
public MyIntentService() {
super("MyIntentService");
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate");
sendServiceState("onCreate");
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Log.i(TAG, "");
}
@Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG, "onHandleIntent thread:"+Thread.currentThread());
String action = intent.getAction();
if(action.equals(ACTION_DOWN_IMG)){
for(int i = 0; i < 100; i++){
try{ //模拟耗时操作
Thread.sleep(50);
}catch (Exception e) {
}
sendProgress(i);
}
}else if(action.equals(ACTION_DOWN_VID)){
for(int i = 0; i < 100; i++){
try{ //模拟耗时操作
Thread.sleep(70);
}catch (Exception e) {
}
sendProgress(i);
}
}
Log.i(TAG, "onHandleIntent end");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
sendServiceState("onDestroy");
}
//发送Service的状态
private void sendServiceState(String state){
Intent intent = new Intent();
intent.setAction(ACTION_SERVICE_STATE);
intent.putExtra(SERVICE_STATE, state);
sendBroadcast(intent);
}
//发送进度
private void sendProgress(int progress){
Intent intent = new Intent();
intent.setAction(ACTION_DOWN_PROGRESS);
intent.putExtra(PROGRESS, progress);
sendBroadcast(intent);
}
}
使用IntentService的方法:
1.继承IntentService。
2.实现不带参数的构造方法,并且调用父类IntentService的构造方法。
3.实现onHandleIntent方法。
3 IntentService源码解析
路径:frameworks/base/core/java/android/app/IntentService.java
先看下IntentService的构造方法和onCreate()。
public abstract class IntentService extends Service {
//Creates an IntentService. Invoked by your subclass's constructor.
public IntentService(String name) {
super();
mName = name;
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
...
}
IntentService 是继承Service的一个抽象类,所以需要继承IntentService 并必须实现其抽象方法onHandleIntent。
继承IntentService需要实现一个空的构造器,并且调用IntentService的构造器。
在onCreate()方法中创建了一个HandlerThread,并允许该线程。
获取子线程中的Looper实例,然后创建与子线程绑定的Handler对象。
接着看IntentService的onStart()。
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
在onStart方法中,创建Message对象,并将“消息”通过mServiceHandler发送到子线程中的消息队列中。
我们知道这些消息处理还是会分发到Handler中。接着看mServiceHandler
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);
}
}
消息会在handlerMessage中处理,该方法中调用了onHandleIntent,所以我们需要实现onHandleIntent,在该方法中做我们要做的任务。而消息处理完成后,调用stopSelf将自身Service销毁。这里可能会有疑问,既然一个任务执行完成后就会执行stopSelf,那多个任务是怎么处理的呢?这里stopSelf(msg.arg1),会先看队列中是否有消息待处理,如果有则继续处理后面的消息,没有才会将Service销毁。
接着看IntentService的onDestroy方法
@Override
public void onDestroy() {
mServiceLooper.quit();
}
在IntentService的onDestroy方法中会调用looper的quit方法,将子线程的消息循环停止,等待任务完成后结束子线程。
4 总结
IntentService是一个比较便捷的类,省了我们在创建Thread,但是并不能适合所有的情况,它会创建一个线程,多个任务按顺序执行,并且执行过程中不能够取消该任务。所以还是需要根据情况进行使用。