IntentService详解(附个推IntentService示例)
1. 什么是IntentService?
- IntentService继承Service,内部创建了HandlerThread和异步线程的Handler来进行耗时操作
- 启动方式和Service一样
- 在开启IntentService时,会回调执行onHandleIntent方法(异步线程中执行,非UI线程)
- 执行完成后会自动停止,不需要额外调用stopSelf()。
- 可以多次启动IntentService,不会有多个实例,只会多次回调onHandleIntent方法。
2. IntentService的使用方法
-
继承IntentService,复写构造方法和onHandleIntent方法
public class MyIntentService extends IntentService{
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public MyIntentService(String name) {
super(name);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
int arg = intent.getIntExtra("arg", 0);
switch(arg){
case 1:
//第一种情况处理
break;
case 2:
//第二种情况处理
break;
case 0:
//第三种情况处理
break;
}
}
} -
在manifest文件中注册IntentService
<service android:name=".intentservice.MyIntentService">
</service> -
通过startService启动IntentService
Intent i = new Intent(this,MyIntentService.class);
i.putExtra("arg",2);
startService(i); -
借鉴一下个推的IntentService的onHandleIntent相关方法
在onHandleIntent中处理各种不同的情况,然后使用工厂方法模式,让子类实现那些未实现的接口,来执行不同的操作:接收消息的处理、设备是否在线的回调等。
protected void onHandleIntent(Intent var1) {
if(var1 != null) {
try {
this.processOnHandleIntent(var1);
} catch (Throwable var3) {
a.b("GTIntentService|" + var3.toString());
}
}
}
private void processOnHandleIntent(Intent var1) {
Bundle var2 = var1.getExtras();
if(var2 != null && var2.get("action") != null && var2.get("action") instanceof Integer) {
switch(var2.getInt("action")) {
case 10001:
this.onReceiveMessageData(this, (GTTransmitMessage)var1.getSerializableExtra("transmit_data"));
break;
case 10002:
this.onReceiveClientId(this, var2.getString("clientid"));
case 10003:
case 10004:
case 10005:
case 10006:
case 10009:
default:
break;
case 10007:
this.onReceiveOnlineState(this, var2.getBoolean("onlineState"));
break;
case 10008:
this.onReceiveServicePid(this, var2.getInt("pid"));
break;
case 10010:
this.onReceiveCommandResult(this, (GTCmdMessage)var1.getSerializableExtra("cmd_msg"));
}
}
}
3. IntentService源码解析
-
onStart方法
这里是标准的HandlerThread的标准用法,先创建HandlerThread实例,调用start()开启线程。使用HandlerThread中的looper绑定工作线程的Handler。
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);}
-
onStart
在onStart中,调用工作线程的Handler发送消息到消息队列。
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
} -
工作线程的Handler
工作线程的Handler中调用了onHandleIntent方法,onHandleIntent由子类实现,执行耗时操作。最后再执行stopSelf(msg.arg1),此处表示,把消息队列中的消息处理完成后再停止。
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);
}
} -
onBind
不能通过onBindService的方式启动IntentService,回调不到onHandleIntent
public IBinder onBind(Intent intent) {
return null;
}
4. 几种异步框架对比
IntentService: 进程优先级高,属于后台服务
其他异步线程需要绑定前台线程,进程优先级低。