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: 進程優先級高,屬於後臺服務
其他異步線程需要綁定前臺線程,進程優先級低。