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: 进程优先级高,属于后台服务
其他异步线程需要绑定前台线程,进程优先级低。