參考 https://developer.android.google.cn/reference/android/app/IntentService.html
IntentService定義
IntentService繼承與Service,用來處理異步請求。客戶端可以通過startService(Intent)方法傳遞請求給IntentService。IntentService在onCreate()方法中通過HandlerThread單獨(dú)開啟一個線程來依次處理所有Intent請求對象所對應(yīng)的任務(wù),這樣以免事務(wù)處理阻塞主線程(ANR)。執(zhí)行完所一個Intent請求對象所對應(yīng)的工作之后,如果沒有新的Intent請求達(dá)到,則自動停止Service;否則執(zhí)行下一個Intent請求所對應(yīng)的任務(wù)。
IntentService在處理事務(wù)時,還是采用的Handler方式,創(chuàng)建一個名叫ServiceHandler的內(nèi)部Handler,并把它直接綁定到HandlerThread所對應(yīng)的子線程。 ServiceHandler把處理一個intent所對應(yīng)的事務(wù)都封裝到叫做onHandleIntent的抽象方法;因此我們直接實(shí)現(xiàn)抽象方法onHandleIntent,再在里面根據(jù)Intent的不同進(jìn)行不同的事務(wù)處理就可以了。 另外,IntentService默認(rèn)實(shí)現(xiàn)了onbind()方法,返回值為null。
-
源碼
public abstract class IntentService extends Service { private volatile Looper mServiceLooper; private volatile ServiceHandler mServiceHandler; private String mName; private boolean mRedelivery; // 內(nèi)部Handler處理 private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { onHandleIntent((Intent)msg.obj); // 關(guān)閉當(dāng)前Service stopSelf(msg.arg1); } } public IntentService(String name) { super(); mName = name;e; } public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } @Override public void onCreate() { super.onCreate(); HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public void onStart(@Nullable Intent intent, int startId) { // 發(fā)送消息(Intent) Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent; mServiceHandler.sendMessage(msg); } @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override public void onDestroy() { mServiceLooper.quit(); } @Override @Nullable public IBinder onBind(Intent intent) { return null; } // 需要覆蓋該方法進(jìn)行一步處理 @WorkerThread protected abstract void onHandleIntent(@Nullable Intent intent); }
實(shí)現(xiàn)方式
-
定義一個TestIntentService繼承IntentService
public class TestIntentService extends IntentService { // 注意構(gòu)造函數(shù)參數(shù)為空,這個字符串就是WorkThread的名字 public TestIntentService() { super("TestIntentService"); } @Override public void onCreate() { Log.d("TIS","onCreate()"); super.onCreate(); } @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { Log.d("TIS","onStartCommand()"); return super.onStartCommand(intent, flags, startId); } @Override public void onDestroy() { super.onDestroy(); Log.d("TIS","onDestroy()"); } @Override protected void onHandleIntent(@Nullable Intent intent) { if (intent != null) { int taskId = intent.getIntExtra("taskId", -1); // 依次處理Intent請求 switch (taskId) { case 0: Log.d("TIS","handle task0"); break; case 1: Log.d("TIS","handle task1"); break; case 2: Log.d("TIS","handle task2"); break; } } } }
-
Manifest.xml中注冊
<application ........> <activity .../> <service android:name=".service.TestIntentService" /> </application>
-
啟動Service
//同一服務(wù)只會開啟一個WorkThread,在onHandleIntent函數(shù)里依次處理Intent請求。 Intent i0 = new Intent(this, TestIntentService.class); Bundle b0 = new Bundle(); b0.putInt("taskId",0); i0.putExtras(b0); startService(i0); Intent i1 = new Intent(this, TestIntentService.class); Bundle b1 = new Bundle(); b1.putInt("taskId",1); i1.putExtras(b1); startService(i1); Intent i2 = new Intent(this, TestIntentService.class); Bundle b2 = new Bundle(); b2.putInt("taskId",2); i2.putExtras(b2); startService(i2); startService(i1); startService(i0);
-
運(yùn)行結(jié)果及生命周期
D/TIS: onCreate() D/TIS: onStartCommand() D/TIS: handle task0 D/TIS: onStartCommand() D/TIS: onStartCommand() D/TIS: onStartCommand() D/TIS: handle task1 D/TIS: onStartCommand() D/TIS: handle task2 D/TIS: handle task1 D/TIS: handle task0 D/TIS: onDestroy()
-
Android Studio自動創(chuàng)建IntentService如下:
代碼沒做,模板代碼是提供靜態(tài)方法,方便調(diào)用
public class HelloIntentService extends IntentService { // TODO: Rename actions, choose action names that describe tasks that this // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS private static final String ACTION_FOO = "com.cyxoder.interstudy.service.action.FOO"; private static final String ACTION_BAZ = "com.cyxoder.interstudy.service.action.BAZ"; // TODO: Rename parameters private static final String EXTRA_PARAM1 = "com.cyxoder.interstudy.service.extra.PARAM1"; private static final String EXTRA_PARAM2 = "com.cyxoder.interstudy.service.extra.PARAM2"; public HelloIntentService() { super("HelloIntentService"); } /** * Starts this service to perform action Foo with the given parameters. If * the service is already performing a task this action will be queued. * * @see IntentService */ // TODO: Customize helper method public static void startActionFoo(Context context, String param1, String param2) { Intent intent = new Intent(context, HelloIntentService.class); intent.setAction(ACTION_FOO); intent.putExtra(EXTRA_PARAM1, param1); intent.putExtra(EXTRA_PARAM2, param2); context.startService(intent); } /** * Starts this service to perform action Baz with the given parameters. If * the service is already performing a task this action will be queued. * * @see IntentService */ // TODO: Customize helper method public static void startActionBaz(Context context, String param1, String param2) { Intent intent = new Intent(context, HelloIntentService.class); intent.setAction(ACTION_BAZ); intent.putExtra(EXTRA_PARAM1, param1); intent.putExtra(EXTRA_PARAM2, param2); context.startService(intent); } @Override protected void onHandleIntent(Intent intent) { if (intent != null) { final String action = intent.getAction(); if (ACTION_FOO.equals(action)) { final String param1 = intent.getStringExtra(EXTRA_PARAM1); final String param2 = intent.getStringExtra(EXTRA_PARAM2); handleActionFoo(param1, param2); } else if (ACTION_BAZ.equals(action)) { final String param1 = intent.getStringExtra(EXTRA_PARAM1); final String param2 = intent.getStringExtra(EXTRA_PARAM2); handleActionBaz(param1, param2); } } } /** * Handle action Foo in the provided background thread with the provided * parameters. */ private void handleActionFoo(String param1, String param2) { // TODO: Handle action Foo throw new UnsupportedOperationException("Not yet implemented"); } /** * Handle action Baz in the provided background thread with the provided * parameters. */ private void handleActionBaz(String param1, String param2) { // TODO: Handle action Baz throw new UnsupportedOperationException("Not yet implemented"); }
-
原理
IntentService在onCreate()函數(shù)中通過HandlerThread單獨(dú)開啟一個線程來依次處理所有Intent請求對象所對應(yīng)的任務(wù)。通過onStartCommand()傳遞給服務(wù)intent被依次插入到工作隊列中。工作隊列又把intent逐個發(fā)送給onHandleIntent()。
注意:所有請求都是在一個單獨(dú)的工作線程上處理的——它們可能會在必要的時候(并不會阻塞應(yīng)用程序的主循環(huán)),但每次只處理一個請求。