Android 中的 IntentService 類詳解

Android Service 代碼地址

Android 中的 IntentService 類詳解

簡介、與 Service 的區別

IntentService 繼承至 Service ,所以 Service 的特點 IntentService 也全部擁有。首先,我們看一下 Service 的一些問題:

  1. Service 默認運行在主線程,不能執行耗時操作;
  2. 如果要在 Service 中執行耗時的操作,需要在 Service 中創建新的線程,但是這就會導致我們不知道在什么時候線程會執行完,也就會導致停止 Service 的時間的未知性。

針對上面的問題,IntentService 擴展了 Service 的功能,完美解決的這個問題,以下是 IntentService 的主要特征:

  1. 會創建獨立的工作線程來處理 onHandleIntent() 方法實現的代碼,無需處理多線程問題;
  2. 所有請求處理完成后,IntentService 會自動停止,無需調用 stopSelf() 方法停止 Service
  3. ServiceonBind() 提供默認實現,返回 null
  4. ServiceonStartCommand() 提供默認實現,將請求 Intent 添加到隊列中。

好處

IntentService 的好處可以根據其特征來分析,主要體現在:

  • 會創建獨立的工作線程處理耗時操作,無需擔心阻塞主線程
  • 無需關在什么時候停止服務,當線程執行完成之后會自動停止服務

使用方式

1.創建 MyIntentService 繼承 IntentService

public class MyIntentService extends IntentService {

    // 必須創建構造方法,調用父類的構造方法
    public MyIntentService() {
        super("intentservice");
    }

    // 在此方法中可以編寫耗時操作的代碼,執行在工作線程
    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        for (int i = 1; i <= 3; i++) {
            // 模擬耗時操作
            SystemClock.sleep(1000 * i);
            Log.i("MyIntentService", "Thread => " + Thread.currentThread().getName());
        }
    }
}

2.IntentService 既然是繼承 Service,那么需要在 AndroidManifest.xml 文件中進行配置

<application>
    ...
    <!-- 服務需要在 AndroidManifest.xml 文件中配置 -->
    <service android:name=".MyIntentService" />
</application>

3.啟動服務

Intent intent = new Intent(this,MyIntentService.class);
startService(intent);

源碼解析

1.構造方法

public IntentService(String name) {
    super();
    mName = name;
}

構造方法只有一個,子類必須重寫構造方法并調用父類的構造方法傳遞 name 值,name 表示 onHandleIntent() 方法所運行的線程名。

2.繼承至 Handler 的內部類 ServiceHandler

private final class ServiceHandler extends Handler {
    // 構造需要一個Looper對象,查看下面的 onCreate() 方法(第4點)
    // 在 onCreate() 方法中創建 ServiceHandler 對象時使用的是從 HandlerThread 中
    // 獲取的 Looper ,所以 handleMessage() 方法處理時在工作線程中
    public ServiceHandler(Looper looper) {
        super(looper);
    }

    // 處理消息的方法
    @Override
    public void handleMessage(Message msg) {
        // 調用方法。抽象方法,子類具體實現
        onHandleIntent((Intent)msg.obj);
        // onHandleIntent() 方法執行完成,停止服務
        stopSelf(msg.arg1);
    }
}

如果對 HandlerThread 類不了解的可以查看 《Android 中的 HandlerThread 類詳解》

3.ServiceHandlerhandleMessage() 方法內部調用的抽象方法

// 抽象方法,方法的執行代碼運行在工作線程
@WorkerThread
protected abstract void onHandleIntent(@Nullable Intent intent);

onHandleIntent() 是抽象方法,子類必須重寫,方法轉給你的內容執行在工作線程。

4.onCreate()方法

@Override
public void onCreate() {
    super.onCreate();
    // 創建 HandlerThread 對象,并啟動線程
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    // 獲取 HandlerThread 中的 Looper 對象,并作為參數用來創建 ServiceHandler 對象
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

如果對 HandlerThread 類不了解的可以查看 《Android 中的 HandlerThread 類詳解》

5.重寫 onStartCommand() / onStart() 方法

@Override
public void onStart(@Nullable Intent intent, int startId) {
    // 將 Intent 發送給 ServiceHandler 進行處理
    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;
}

// 確定 onStartCommand() 方法的返回值,是否需要重啟服務
public void setIntentRedelivery(boolean enabled) {
    mRedelivery = enabled;
}

將請求添加到工作線程的 MessageQueue 隊列中。

6.重寫 onBind() 方法

@Override
@Nullable
public IBinder onBind(Intent intent) {
    return null;
}

提供 onBind() 的默認實現,返回 null

7.銷毀 onDestory() 方法

@Override
public void onDestroy() {
    mServiceLooper.quit();
}

調用 Looperquit() 方法,清除所有的消息。

總結

  • 會創建獨立的工作線程來處理 onHandleIntent() 方法實現的代碼,無需處理多線程問題;
  • 所有請求處理完成后,IntentService 會自動停止,無需調用 stopSelf() 方法停止 Service
  • ServiceonBind() 提供默認實現,返回 null
  • ServiceonStartCommand() 提供默認實現,將請求 Intent 添加到隊列中;
  • IntentService 內部使用的是 HandlerThread ,所以有 HandlerThread 的局限性(HandlerThread 本質是一個線程,在線程內部,代碼是串行處理的;
    由于每一個任務都將以隊列的方式逐個被執行到,一旦隊列中有某個任務執行時間過長,那么就會導致后續的任務都會被延遲處理)。

相關文章

《Android 中的 HandlerThread 類詳解》
《AsyncTask 完全解析》
《Android中的Handler機制分析(一) Handler和Message分析》
《Android中的Handler機制分析(二) MessageQueue分析》
《Android中的Handler機制分析(三) Looper分析和Handler其他知識》

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。