Android IntentService詳解(源碼分析)

目錄:

目錄

1. 前言

本文是對(duì) IntentService 的深入學(xué)習(xí)跪帝,包含其基本使用方法搂蜓、IntentService更新處理UI工作回论,以及對(duì) IntentService 的源碼分析蹦漠。

1.1 定義

IntentService 是 Service 的子類,繼承于 Service 類雨涛,用于處理后臺(tái)異步請(qǐng)求任務(wù)。

用戶通過調(diào)用 Context.StartService(Intent) 發(fā)送請(qǐng)求懦胞,服務(wù)根據(jù)請(qǐng)求啟動(dòng)替久,使用工作線程依次處理每個(gè) Intent任務(wù)請(qǐng)求,并在處理完所有任務(wù)請(qǐng)求后自身停止服務(wù)躏尉。

使用時(shí)蚯根,擴(kuò)展 IntentService ,即實(shí)現(xiàn)它的子類并具體實(shí)現(xiàn) onHandleIntent(android.content.Intent) 方法醇份。IntentService 接收 Intent稼锅,啟動(dòng)工作線程,并在適當(dāng)時(shí)機(jī)停止服務(wù)僚纷。

所有的請(qǐng)求都在同一個(gè)工作線程上處理矩距,一次處理一個(gè)請(qǐng)求,所以處理完所以的請(qǐng)求可能會(huì)花費(fèi)很長(zhǎng)的時(shí)間怖竭,但由于 IntentService 是另外創(chuàng)建的線程來工作锥债,所以保證不會(huì)阻止App 的主線程,防止 App 出現(xiàn) ANR痊臭。

1.2 使用場(chǎng)景

用于處理后臺(tái)長(zhǎng)時(shí)間的耗時(shí)操作哮肚,如:下載文件、播放音樂...

2. 使用方法

由于 IntentService 是抽象類广匙,所以在實(shí)際使用中允趟,我們需要?jiǎng)?chuàng)建一個(gè) IntentService 子類來具體實(shí)現(xiàn)。

使用步驟分為兩步:

  1. 創(chuàng)建 IntentService 子類鸦致,并在清單文件中注冊(cè)潮剪。
  2. 在 Activity 中通過調(diào)用 startService(Intent) 方法發(fā)送任務(wù)請(qǐng)求涣楷。

例子:
我們模擬在后臺(tái)進(jìn)行下載以及讀取文件的耗時(shí)操作,觀察打印出來的 Log 信息抗碰。

如下所示:


MyIntentService處理耗時(shí)操作的日志信息

IntentService 的執(zhí)行流程為:onCreate() -> onStartCommand() -> onStart() -> onHandleIntent -> ···處理完所有請(qǐng)求··· -> onDestroy()

具體代碼如下所示:分 Java & Kotlin 兩個(gè)版本展示狮斗。

2.1 Java版本

步驟一:創(chuàng)建 MyIntentService

public class MyIntentService extends IntentService {

    private static final String TAG = "MyIntentService";
    public static final String DOWNLOAD_ACTION = "DOWNLOAD_ACTION";
    public static final String READ_ACTION = "READ_ACTION";
    public static final String TEST_AUTHOR = "TEST_AUTHOR";

    public MyIntentService() {
        super("MyIntentService");
    }

    /**
     * 進(jìn)行一些耗時(shí)操作
     * @param intent 通過startService(Intent intent)方法傳入
     */
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.e(TAG, "onHandleIntent: ");
        if (intent != null) {
            final String action = intent.getAction();
            String author = intent.getExtras().getString(TEST_AUTHOR);
            //模擬下載動(dòng)作
            if (DOWNLOAD_ACTION.equals(action)) {
                for (int i = 0; i < 5; i++) {
                    try {
                        //線程等待1s,模擬耗時(shí)操作
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.e(TAG, author + " " + action + " " + i);
                }
            }
            //模擬讀操作
            if (READ_ACTION.equals(action)) {
                for (int i = 0; i < 5; i++) {
                    try {
                        //線程等待2s弧蝇,模擬耗時(shí)操作
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.e(TAG, author + " " + action + " " + i);
                }
            }
        }

    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "onCreate", Toast.LENGTH_SHORT).show();
        Log.e(TAG, "onCreate: ");
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        Toast.makeText(this, "onStartCommand", Toast.LENGTH_SHORT).show();
        Log.e(TAG, "onStartCommand: ");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.e(TAG, "onStart: ");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy: ");
        Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show();
    }
}

并記得在清單文件中注冊(cè)碳褒,這一步你也可以通過 Android Studio 來幫我們完成

<service
    android:name=".intentservice.MyIntentService"
    android:exported="false">
</service>

步驟二:通過 startService(Intent) 發(fā)送任務(wù)請(qǐng)求

public class IntentServiceActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_service);

        //模擬 Jere 做下載動(dòng)作
        Intent intent = new Intent(this, MyIntentService.class);
        intent.setAction(MyIntentService.DOWNLOAD_ACTION);
        intent.putExtra(MyIntentService.TEST_AUTHOR, "Jere");
        startService(intent);

        //模擬 James 做讀取動(dòng)作
        Intent jamesIntent = new Intent(this, MyIntentService.class);
        jamesIntent.setAction(MyIntentService.READ_ACTION);
        jamesIntent.putExtra(MyIntentService.TEST_AUTHOR, "James");
        startService(jamesIntent);
    }
}

2.2 Koltin版本

步驟一:創(chuàng)建 MyIntentService

class MyIntentService : IntentService("MyIntentService") {
    companion object {
        private val TAG: String = "MyIntentService"
        val DOWNLOAD_ACTION = "DOWNLOAD_ACTION"
        val READ_ACTION = "READ_ACTION"
        val TEST_AUTHOR = "TEST_AUTHOR"
    }


    override fun onHandleIntent(intent: Intent?) {
        val action: String? = intent?.action
        val author: String? = intent?.extras?.getString(TEST_AUTHOR)

        when (intent?.action) {
            DOWNLOAD_ACTION -> {
                for (i in 0..10) {
                    Thread.sleep(1000)
                    Log.e(TAG, "$author $action $I")
                }
            }
            READ_ACTION -> {
                for (j in 0..10) {
                    Thread.sleep(2000)
                    Log.e(TAG, "$author $action $j")
                }
            }
        }
    }

    override fun onCreate() {
        super.onCreate()
        Log.e(TAG, "onCreate")
        Toast.makeText(this, "conCreate", Toast.LENGTH_SHORT).show()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.e(TAG, "onStartCommand")
        Toast.makeText(this, "onStartCommand", Toast.LENGTH_SHORT).show()
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.e(TAG, "onDestroy")
        Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show()
    }
}

在清單文件中注冊(cè):

<service
    android:name=".multiplethread.intentservice.MyIntentService"
    android:exported="false">
</service>

步驟二:通過 startService(Intent) 發(fā)送任務(wù)請(qǐng)求

class TestIntentServiceActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test_intent_service)

        val intent = Intent()
        intent.setClass(this, MyIntentService::class.java)
        intent.action = MyIntentService.DOWNLOAD_ACTION
        intent.putExtra(MyIntentService.TEST_AUTHOR, "Jere")
        startService(intent)

        val jamesIntent = Intent()
        jamesIntent.setClass(this, MyIntentService::class.java)
        jamesIntent.action = MyIntentService.READ_ACTION
        jamesIntent.putExtra(MyIntentService.TEST_AUTHOR, "James")
        startService(jamesIntent)
    }
}

2.3 IntentService更新處理UI工作

思考: 在上面的例子中,我們是通過在打印出來的日志信息來觀察后臺(tái)異步任務(wù)的執(zhí)行情況看疗,那 IntentService 可以處理 UI 工作嗎沙峻?

答: IntentService 是服務(wù)端,肯定是不可以處理 UI 工作的两芳,但是他可以通過其對(duì)應(yīng)的客戶端专酗,也就是 Activity 來更新處理 UI 工作。

客戶端與服務(wù)端之間的通信

客戶端與服務(wù)端之間的通信盗扇,我們使用 Messenger 祷肯,關(guān)于 Messenger 內(nèi)容請(qǐng)看另一篇博客 Android Messenger初探,具體實(shí)現(xiàn)如下所示:

例子: 我們?cè)?IntentService 模擬下載任務(wù)疗隶,通過 ProgressBar 顯示下載進(jìn)度佑笋。

效果圖如下所示:


intentService更新處理UI工作.gif

具體代碼如下所示:分Java & Kotlin 兩個(gè)版本展示。

2.3.1 Java版本

  1. 在 Activity 中發(fā)送請(qǐng)求時(shí)斑鼻,新建一個(gè) Messenger 對(duì)象蒋纬,傳遞給 IntentService。
public class IntentServiceActivity extends AppCompatActivity {
    private ProgressBar downloadProgressBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_intent_service);

        downloadProgressBar = findViewById(R.id.download_progress_bar);

        //用于創(chuàng)建 Messenger坚弱,接收 IntentService 回復(fù)的消息
        MessengerHandler messengerHandler = new MessengerHandler(this);

        //模擬 Jere 做下載動(dòng)作
        Intent intent = new Intent(this, MyIntentService.class);
        intent.setAction(MyIntentService.DOWNLOAD_ACTION);
        intent.putExtra(MyIntentService.TEST_AUTHOR, "Jere");
        //將 Messenger 傳遞給 IntentService蜀备,讓其回復(fù)消息回來
        intent.putExtra(MyIntentService.TEST_MESSENGER, new Messenger(messengerHandler));
        startService(intent);
    }

    /**
     * 用于創(chuàng)建 Messenger 對(duì)象
     * 
     * 靜態(tài)內(nèi)部類,防止內(nèi)存泄漏
     */
    public static class MessengerHandler extends Handler {
        private WeakReference<IntentServiceActivity> weakReference;

        MessengerHandler(IntentServiceActivity activity) {
            weakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            //msg 為 IntentService 回復(fù)的消息荒叶,包含 Bundle 等信息碾阁。
            Bundle bundle = msg.getData();
            //獲取 IntentService 傳遞過來的 下載進(jìn)度 參數(shù)
            int downloadProgressBarValue = bundle.getInt(MyIntentService.DOWNLOAD_PROGRESS_VALUE_KEY);

            //將下載進(jìn)度設(shè)置成 ProgressBar 的進(jìn)度,顯示出來些楣。
            IntentServiceActivity activity = weakReference.get();
            if (activity != null && !activity.isFinishing()) {
                activity.downloadProgressBar.setProgress(downloadProgressBarValue);
            }

        }
    }

}
  1. 在 IntentService 中獲取 Messenger 對(duì)象脂凶,并回復(fù)消息給 Activity。
public class MyIntentService extends IntentService {

    private static final String TAG = "MyIntentService";
    public static final String DOWNLOAD_ACTION = "DOWNLOAD_ACTION";
    public static final String READ_ACTION = "READ_ACTION";
    public static final String TEST_AUTHOR = "TEST_AUTHOR";
    public static final String TEST_MESSENGER = "TEST_MESSENGER";
    public static final String DOWNLOAD_PROGRESS_VALUE_KEY = "DOWNLOAD_PROGRESS_VALUE";

    public MyIntentService() {
        super("MyIntentService");
    }

    /**
     * 進(jìn)行一些耗時(shí)操作
     * @param intent 通過startService(Intent intent)方法傳入
     */
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.e(TAG, "onHandleIntent: ");
        if (intent != null) {
            final String action = intent.getAction();
            String author = intent.getExtras().getString(TEST_AUTHOR);

            //模擬下載動(dòng)作
            if (DOWNLOAD_ACTION.equals(action)) {
                for (int i = 0; i <= 6; i++) {
                    try {
                        //線程等待1s愁茁,模擬耗時(shí)操作
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    Log.e(TAG, author + " " + action + " " + i);
                    //獲取從 Activity 傳入的 Messenger
                    Messenger messenger = (Messenger) intent.getExtras().get(TEST_MESSENGER);
                    //新建消息蚕钦,設(shè)置下載進(jìn)度參數(shù)
                    Message msg = new Message();
                    Bundle bundle = new Bundle();
                    bundle.putInt(DOWNLOAD_PROGRESS_VALUE_KEY, i);
                    msg.setData(bundle);
                    try {
                        //回復(fù)消息
                        messenger.send(msg);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }

    @Override
    public void onCreate() {
        super.onCreate();
        Toast.makeText(this, "onCreate", Toast.LENGTH_SHORT).show();
        Log.e(TAG, "onCreate: ");
    }

    @Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        Toast.makeText(this, "onStartCommand", Toast.LENGTH_SHORT).show();
        Log.e(TAG, "onStartCommand: ");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        super.onStart(intent, startId);
        Toast.makeText(this, "onStart", Toast.LENGTH_SHORT).show();
        Log.e(TAG, "onStart: ");
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e(TAG, "onDestroy: ");
        Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show();
    }

}

這樣就實(shí)現(xiàn)了 IntentService 更新處理 UI 工作,具體效果看上圖 IntentService更新處理UI工作鹅很。

2.3.2 Kotlin版本

同樣嘶居,Kotlin的實(shí)現(xiàn)方式為:

  1. 在 Activity 中發(fā)送請(qǐng)求時(shí),新建一個(gè) Messenger 對(duì)象促煮,傳遞給 IntentService邮屁。
class TestIntentServiceActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test_intent_service)

        val intent = Intent()
        intent.setClass(this, MyIntentService::class.java)
        intent.action = MyIntentService.DOWNLOAD_ACTION_KEY
        intent.putExtra(MyIntentService.TEST_AUTHOR_KEY, "Jere")
        //將 Messenger 傳遞給 IntentService, 使其傳遞消息回來胸蛛,實(shí)現(xiàn)客戶端與服務(wù)端之間進(jìn)行溝通
        intent.putExtra(MyIntentService.TEST_MESSENGER_KEY, Messenger(MessengerHandler(this)))
        startService(intent)
    }

    /**
     * 此 Handler 用于創(chuàng)建 Messenger 對(duì)象,接收 IntentService 回復(fù)回來的消息
     *
     * 靜態(tài)內(nèi)部類樱报,防止內(nèi)存泄漏
     */
    class MessengerHandler(activity: TestIntentServiceActivity) : Handler() {
        var weakReference: WeakReference<TestIntentServiceActivity> = WeakReference(activity)

        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            //msg 為 IntentService 回復(fù)的消息,包含 Bundle 等信息泞当。
            val bundle: Bundle = msg.data
            //獲取 IntentService 傳遞過來的 下載進(jìn)度 參數(shù)
            val downloadProgressBarValue: Int =
                bundle.get(MyIntentService.DOWNLOAD_PROGRESS_BAR_VALUE_KEY) as Int
            val activity: TestIntentServiceActivity? = weakReference.get()
            //將下載進(jìn)度設(shè)置成 ProgressBar 的進(jìn)度迹蛤,顯示出來。
            if (activity != null && !activity.isFinishing) {
                activity.intentServiceDownloadProgressBar.progress = downloadProgressBarValue
            }
        }
    }
}
  1. 在 IntentService 中獲取 Messenger 對(duì)象襟士,并回復(fù)消息給 Activity盗飒。
class MyIntentService : IntentService("MyIntentService") {
    companion object {
        private val TAG: String = "MyIntentService"
        val DOWNLOAD_ACTION_KEY = "DOWNLOAD_ACTION"
        val READ_ACTION_KEY = "READ_ACTION"
        val TEST_AUTHOR_KEY = "TEST_AUTHOR"
        val TEST_MESSENGER_KEY = "TEST_MESSENGER"
        val DOWNLOAD_PROGRESS_BAR_VALUE_KEY = "DOWNLOAD_PROGRESS_BAR_VALUE"
    }

    override fun onHandleIntent(intent: Intent?) {
        val action: String? = intent?.action
        val author: String? = intent?.extras?.getString(TEST_AUTHOR_KEY)

        when (intent?.action) {
            DOWNLOAD_ACTION_KEY -> {
                for (i in 0..6) {
                    Thread.sleep(1000)
                    Log.e(TAG, "$author $action $I")
                    //獲取從 Activity 中傳入的 Messenger 對(duì)象
                    val messenger: Messenger = intent.extras?.get(TEST_MESSENGER_KEY) as Messenger
                    //新建一個(gè) Message 對(duì)象
                    val msg: Message = Message()
                    //為 Message 對(duì)象設(shè)置 下載進(jìn)度 參數(shù)
                    val bundle: Bundle = Bundle()
                    bundle.putInt(DOWNLOAD_PROGRESS_BAR_VALUE_KEY, i)
                    msg.data = bundle
                    //Messenger 回復(fù)消息給 Activity
                    messenger.send(msg)
                }
            }
            READ_ACTION_KEY -> {
                for (j in 0..10) {
                    Thread.sleep(2000)
                    Log.e(TAG, "$author $action $j")
                }
            }
        }
    }

    override fun onCreate() {
        super.onCreate()
        Log.e(TAG, "onCreate")
        Toast.makeText(this, "onCreate", Toast.LENGTH_SHORT).show()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.e(TAG, "onStartCommand")
        Toast.makeText(this, "onStartCommand", Toast.LENGTH_SHORT).show()
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onStart(intent: Intent?, startId: Int) {
        super.onStart(intent, startId)
        Log.e(TAG, "onStart")
        Toast.makeText(this, "onStart", Toast.LENGTH_SHORT).show()
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.e(TAG, "onDestroy")
        Toast.makeText(this, "onDestroy", Toast.LENGTH_SHORT).show()
    }
}

具體效果看上圖 IntentService更新處理UI工作

3. 源碼分析

上面介紹了 IntentService 的使用方法陋桂,接下來逆趣,我們來看一下 IntentService 的源碼。如果你理解了 Hander嗜历、Looper宣渗、MessageQueue三者之間的關(guān)系,那么理解 IntentService 的源代碼十分容易梨州。(如果不理解痕囱,請(qǐng)看博客 Android Handler深入學(xué)習(xí)(源碼分析)

根據(jù)上面的例子,我們知道了 IntentService 的執(zhí)行順序?yàn)椋?/p>

onCreate() -> onStartCommand() -> onStart() -> onHandleIntent -> ···處理完所有請(qǐng)求··· -> onDestroy()

IntentService 源碼如下:

public abstract class IntentService extends Service {
    private volatile Looper mServiceLooper;
    private volatile ServiceHandler mServiceHandler;
    private String mName;
    private boolean mRedelivery;

    //創(chuàng)建一個(gè)內(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);
            stopSelf(msg.arg1);
        }
    }

    /**
     * IntentService 構(gòu)造函數(shù),在你的子類構(gòu)造函數(shù)中調(diào)用(在子類中通過 super(name) 方法調(diào)用)
     *
     * @param 參數(shù) name 用于命名工作線程
     * 
     */
    public IntentService(String name) {
        super();
        mName = name;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        //創(chuàng)建一個(gè) HandlerThread 對(duì)象
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        //啟動(dòng) HandlerThread 線程
        thread.start();
        //獲取 HandlerThread 中創(chuàng)建的 Looper 對(duì)象每窖,賦值給全局變量 mServiceLooper帮掉。
        mServiceLooper = thread.getLooper();
        //創(chuàng)建一個(gè) Handler 對(duì)象,并關(guān)聯(lián)剛剛通過 HandlerThread 創(chuàng)建的 Looper 對(duì)象窒典,即關(guān)聯(lián) mServiceLooper
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }

    @Override
    public void onStart(@Nullable Intent intent, int startId) {
        //發(fā)送消息給 mServiceHanlder蟆炊,
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }

    /**
     * 你不應(yīng)該在你的 IntentService 類中復(fù)寫 onStartCommand() 方法。
     * 相反瀑志,你應(yīng)該復(fù)寫 onHandleIntent() 方法盅称,該方法會(huì)在 IntentService 接收到啟動(dòng)請(qǐng)求時(shí)被調(diào)用。
     */
    @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() {
        //退出 Looper 消息循環(huán)
        mServiceLooper.quit();
    }

    /**
     * 除非是綁定服務(wù)后室,否則你不需要實(shí)現(xiàn)此方法缩膝,因?yàn)榇朔椒ǖ哪J(rèn)實(shí)現(xiàn)返回 null.
     */
    @Override
    @Nullable
    public IBinder onBind(Intent intent) {
        return null;
    }

    /**
     * 此方法在工作線程中被調(diào)用用于處理請(qǐng)求,一次只能處理一個(gè)請(qǐng)求岸霹,處理工作運(yùn)行于獨(dú)立于其他應(yīng)用程序的工作線程中疾层。
     * 因此,如果該段代碼花費(fèi)了很長(zhǎng)的一段時(shí)間贡避,它會(huì)阻塞同一個(gè) IntentService 的其他請(qǐng)求痛黎,但不會(huì)阻塞其他任何東西予弧。
     * 當(dāng)所有的請(qǐng)求都被處理完,該 IntentService 就會(huì)停止運(yùn)行湖饱,所以你不用調(diào)用 stopSelf() 方法掖蛤。
     *
     * @param intent 通過 startService(Intent) 方法傳入。如果服務(wù)在其進(jìn)程消失后重新啟動(dòng)井厌,則此值可能為空;
     */
    @WorkerThread
    protected abstract void onHandleIntent(@Nullable Intent intent);
}

總結(jié):

  1. 在 onCreate() 方法中蚓庭,我們新建一個(gè) HandlerThread 對(duì)象,然后啟用它仅仆,獲取其創(chuàng)建的 Looper 對(duì)象器赞,然后新創(chuàng)建一個(gè) Looper 對(duì)象關(guān)聯(lián)該 Looper 對(duì)象。關(guān)于 HandlerThread 的知識(shí)點(diǎn)請(qǐng)看另一篇博客 Android HandlerThread詳解(源碼分析)
  2. 然后我們?cè)?onStart() 方法中墓拜,通過 Message港柜,將 Intent任務(wù)請(qǐng)求 發(fā)送給 mServiceHandler,Intent任務(wù)請(qǐng)求就是我們?cè)?Activity 中通過 startService(Intent) 傳入的 Intent咳榜。
  3. mServiceHanlder 接受到任務(wù)請(qǐng)求夏醉,調(diào)用 onHandleIntent() 方法處理任務(wù)請(qǐng)求,處理完所有請(qǐng)求后涌韩,調(diào)用 stopSelf() 結(jié)束 IntentService授舟。

至此 HandlerThread 的源碼也就分析結(jié)束了。
其實(shí)分享文章的最大目的正是等待著有人指出我的錯(cuò)誤贸辈,如果你發(fā)現(xiàn)哪里有錯(cuò)誤释树,請(qǐng)毫無保留的指出即可,虛心請(qǐng)教擎淤。

另外奢啥,如果你覺得文章不錯(cuò),對(duì)你有所幫助嘴拢,請(qǐng)給我點(diǎn)個(gè)贊桩盲,就當(dāng)鼓勵(lì),謝謝~Peace~席吴!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末赌结,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子孝冒,更是在濱河造成了極大的恐慌柬姚,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,126評(píng)論 6 520
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庄涡,死亡現(xiàn)場(chǎng)離奇詭異量承,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,421評(píng)論 3 400
  • 文/潘曉璐 我一進(jìn)店門撕捍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拿穴,“玉大人,你說我怎么就攤上這事忧风∧” “怎么了?”我有些...
    開封第一講書人閱讀 169,941評(píng)論 0 366
  • 文/不壞的土叔 我叫張陵狮腿,是天一觀的道長(zhǎng)腿宰。 經(jīng)常有香客問我,道長(zhǎng)蚤霞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,294評(píng)論 1 300
  • 正文 為了忘掉前任义钉,我火速辦了婚禮昧绣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘捶闸。我一直安慰自己夜畴,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,295評(píng)論 6 398
  • 文/花漫 我一把揭開白布删壮。 她就那樣靜靜地躺著贪绘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪央碟。 梳的紋絲不亂的頭發(fā)上税灌,一...
    開封第一講書人閱讀 52,874評(píng)論 1 314
  • 那天,我揣著相機(jī)與錄音亿虽,去河邊找鬼菱涤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛洛勉,可吹牛的內(nèi)容都是我干的粘秆。 我是一名探鬼主播,決...
    沈念sama閱讀 41,285評(píng)論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼收毫,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼攻走!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起此再,我...
    開封第一講書人閱讀 40,249評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤昔搂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后输拇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巩趁,經(jīng)...
    沈念sama閱讀 46,760評(píng)論 1 321
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,840評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了议慰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蠢古。...
    茶點(diǎn)故事閱讀 40,973評(píng)論 1 354
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖别凹,靈堂內(nèi)的尸體忽然破棺而出草讶,到底是詐尸還是另有隱情,我是刑警寧澤炉菲,帶...
    沈念sama閱讀 36,631評(píng)論 5 351
  • 正文 年R本政府宣布堕战,位于F島的核電站,受9級(jí)特大地震影響拍霜,放射性物質(zhì)發(fā)生泄漏嘱丢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,315評(píng)論 3 336
  • 文/蒙蒙 一祠饺、第九天 我趴在偏房一處隱蔽的房頂上張望越驻。 院中可真熱鬧,春花似錦道偷、人聲如沸缀旁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,797評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽并巍。三九已至,卻和暖如春换途,著一層夾襖步出監(jiān)牢的瞬間懊渡,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,926評(píng)論 1 275
  • 我被黑心中介騙來泰國(guó)打工军拟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留距贷,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,431評(píng)論 3 379
  • 正文 我出身青樓吻谋,卻偏偏與公主長(zhǎng)得像忠蝗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子漓拾,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,982評(píng)論 2 361