Android:IntentService的學習

Android的四大組件中,Service排行老二,在Android中的主要做用是後臺服務,進行與界面無關的操做。因爲Service運行在主線程,因此進行異步操做須要在子線進行。爲此Android爲咱們提供了IntentServiceIntentService是一個抽象類,繼承至Service,主要方便咱們新建工做線程進行異步操做。提交任務到IntentService時,異步任務以串行方式進行處理,意味着工做線程一次只處理一個任務。並且當全部任務都完成以後,會自動中止Service,不須要咱們手動中止。android

IntentService 的使用

  1. 咱們定義DownloadService類並繼承至IntentService。來模擬網絡下載的過程。
public class DownloadService extends IntentService {

    private static int count = 0;

    /**
     * 主要用於調用服務類構造器
     *
     * @param name 用於區分不一樣任務
     */
    public DownloadService(String name) {
        super(name);
    }

    /**
     * AndroidManifest.xml配置清單須要配置
     *
     * @param
     */
    public DownloadService() {
        super("action");
    }

    /**
    *主要重寫該方法,在該方法內進行異步操做。
    **/
    @Override
    protected void onHandleIntent(Intent intent) {
        Log.i("Download", "onHandleIntent" + count);
        count++;

        String name = intent.getStringExtra("action");

        if (name.equals("download")) {
            for (int i = 0; i < 5; i++) {

                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    return;
                }

                Log.i("Download", "download:" + count);
            }
        }
    }
    //如下方法的重寫,僅僅爲了打印日誌
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("Download", "onDestroy");

    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("Download", "onCreate");
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);

        Log.i("Download", "onStart");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.i("Download", "onStartCommand");
        return super.onStartCommand(intent, flags, startId);
    }
}

複製代碼
  1. 在AndroidManifest.xml配置DownloadService
<service android:name=".DownloadService"/>
複製代碼
  1. 在MainActivity類中循環調用Service,啓動多循環任務。
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent=new Intent(this,DownloadService.class);
        for (int i =0;i<3;i++){

            intent.putExtra("action","download");
            intent.putExtra("count",""+i);
            startService(intent);

        }
    }
複製代碼
  1. 運行結果

分析: 從運行結果知道,IntentService在運行多個任務狀況下,只調用一次onCreate,調用屢次onStartCommand,跟Service的生命週期一致。但,只有在運行完download:1以後纔會去運行download:2,接着是download:3。最後全部任務結束後會自動調用onDestroy,中止服務。在這裏須要注意的是,和Service並不一樣,Service須要咱們手動中止服務。對於結果的回調,能夠採用接口回調,廣播,EventBusbash

那麼,IntentService是如何在Service中實現異步操做和串行處理任務的呢?網絡

IntentService內部實現

  1. 查看IntentService的onCreate方法
@Override
    public void onCreate() {
        super.onCreate();
        //分析一
        HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
        thread.start();

        mServiceLooper = thread.getLooper();
        分析二
        mServiceHandler = new ServiceHandler(mServiceLooper);
    }
複製代碼

分析一異步

HandThread繼承Thread,經過start方法建立工做線程,內部創建Looper來達到消息循環,經過Hanlder消息機制來達到串行的效果和處理多任務。HandThreadHandler消息機制,能夠另外查看文章。ide

分析二oop

ServiceHandler繼承Handler,與普通的Handler並無區別,在其內容處理handleMessage。即調用IntentServiceonHandleIntentpost

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);
        }
    }
複製代碼
  1. 那麼,當咱們在Activity中重複調用startService方法時,只會屢次調用onStartCommand方法,並不會重複調用onCreate方法。咱們看看onStartComamnd方法的實現。
@Override
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
        onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }
複製代碼

能夠看得出,調用了onStart方法了。而onStart方法只是將咱們的Intent包裝成Message,經過Handler發送出去,並在Handler中進行處理,調用咱們的onHandleIntent。進而調用咱們實現onHandleIntent的代碼。ui

@Override
    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }
複製代碼

總結

IntentService並無什麼的新的技術含量,在瞭解HandlerTread和Handler的消息機制下,對Handler+Thread+Service做一個封裝,更適合咱們後臺進行異步耗時操做的場景。有效避免經過new多個Threadthis

知識點分享spa

Android消息機制

HandlerThread必知必會

點個贊,老鐵

若是以爲文章有用,給文章點個贊,鐵子
相關文章
相關標籤/搜索