4.IntentService源碼分析php
IntentService的介紹android
IntentService的做用git
目前,因爲正式項目中application初始化工做太多,因此決定分擔部分邏輯到IntentService中處理 好比:如今application初始化內容有:數據庫初始化,阿里雲推送初始化,騰訊bugly初始化,im初始化,神策初始化,內存泄漏工具初始化,頭條適配方案初始化,阿里雲熱修復……等等。將部分邏輯放到IntentService中處理,能夠縮短不少時間。
步驟1:定義InitializeService類,而且須要繼承IntentService的子類github
//第一步 InitializeService.start(this); //第二步 <service android:name=".InitializeService"/> //第三步 public class InitializeService extends IntentService { private static final String ACTION_INIT = "initApplication"; public static void start(Context context) { Intent intent = new Intent(context, InitializeService.class); intent.setAction(ACTION_INIT); context.startService(intent); } public InitializeService(){ //注意這裏須要寫類的名稱 super("InitializeService"); } @Override protected void onHandleIntent(Intent intent) { if (intent != null) { final String action = intent.getAction(); if (ACTION_INIT.equals(action)) { initApplication(); } } } private void initApplication() { //處理耗時操做和避免在application作過多初始化工做,好比初始化數據庫等等 } }
IntentService實際上內部實例化了一個HandlerThread,而且封裝了一個Handler,因此他的工做流程經過上面的源碼,分析以下:數據庫
/** * <pre> * @author yangchong * blog : https://github.com/yangchong211 * time : 2017/01/22 * desc : 初始化工做,子線程,處理耗時操做和避免在application作過多初始化工做,好比初始化數據庫等等 * revise: * </pre> */ public abstract class IntentService extends Service { //子線程中的Looper private volatile Looper mServiceLooper; //內部持有的一個mServiceHandler對象 private volatile ServiceHandler mServiceHandler; //內部建立的線程名字 private String mName; //服務被異常終止後從新建立調用onStartCommand是否回傳Intent private boolean mRedelivery; /** * 內部建立了一個ServiceHandler,而後將傳遞過來的Intent封裝成一個Message, * 而後再將Message封裝成一個Intent,回調onHandleIntent,其實轉換的目的就是 * 將主線程的Intent切換到子線程中去執行了而已。 */ private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { //處理髮送過來的消息,在子線程 onHandleIntent((Intent)msg.obj); //處理完消息以後中止Service stopSelf(msg.arg1); } } /** * 工做線程的名字 * @param name name */ public IntentService(String name) { super(); mName = name; } public void setIntentRedelivery(boolean enabled) { mRedelivery = enabled; } @Override public void onCreate() { super.onCreate(); //建立HandlerThread HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); //開啓線程建立子線程Looper thread.start(); //獲取子線程Looper mServiceLooper = thread.getLooper(); //建立子線程Handler mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public void onStart(@Nullable Intent intent, int startId) { //建立一個Message Message msg = mServiceHandler.obtainMessage(); //消息標誌,做爲當前Service的標誌 msg.arg1 = startId; //攜帶Intent msg.obj = intent; //發送消息,此時將線程切換到子線程 mServiceHandler.sendMessage(msg); } @Override public int onStartCommand(@Nullable Intent intent, int flags, int startId) { //調用onStart方法 onStart(intent, startId); //根據mRedelivery的值來肯定返回重傳Intent的黏性廣播仍是非黏性廣播 return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } @Override public void onDestroy() { //退出Looper mServiceLooper.quit(); } @Override @Nullable public IBinder onBind(Intent intent) { return null; } /*子類必須實現的抽象方法*/ @WorkerThread protected abstract void onHandleIntent(@Nullable Intent intent); }
// IntentService源碼中的 onCreate() 方法 @Override public void onCreate() { super.onCreate(); // HandlerThread繼承自Thread,內部封裝了 Looper //經過實例化andlerThread新建線程並啓動 //因此使用IntentService時不須要額外新建線程 HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); thread.start(); //得到工做線程的 Looper,並維護本身的工做隊列 mServiceLooper = thread.getLooper(); //將上述得到Looper與新建的mServiceHandler進行綁定 //新建的Handler是屬於工做線程的。 mServiceHandler = new ServiceHandler(mServiceLooper); } private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } //IntentService的handleMessage方法把接收的消息交給onHandleIntent()處理 //onHandleIntent()是一個抽象方法,使用時須要重寫的方法 @Override public void handleMessage(Message msg) { // onHandleIntent 方法在工做線程中執行,執行完調用 stopSelf() 結束服務。 onHandleIntent((Intent)msg.obj); //onHandleIntent 處理完成後 IntentService會調用 stopSelf() 自動中止。 stopSelf(msg.arg1); } } //onHandleIntent()是一個抽象方法,使用時須要重寫的方法 @WorkerThread protected abstract void onHandleIntent(Intent intent);
public int onStartCommand(Intent intent, int flags, int startId) { onStart(intent, startId); return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; } public void onStart(Intent intent, int startId) { Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; //把 intent 參數包裝到 message 的 obj 中,而後發送消息,即添加到消息隊列裏 //這裏的Intent 就是啓動服務時startService(Intent) 裏的 Intent。 msg.obj = intent; mServiceHandler.sendMessage(msg); } //清除消息隊列中的消息 @Override public void onDestroy() { mServiceLooper.quit(); }
分析:segmentfault
@Override public IBinder onBind(Intent intent) { return null; }
並不會調用onstart()或者onstartcommand()方法,因此不會將消息發送到消息隊列,那麼onHandleIntent()將不會回調,即沒法實現多線程的操做。多線程