Android面向面試複習----IntentService詳解

IntentService詳解(附個推IntentService示例)

1. 什麼是IntentService?

  • IntentService繼承Service,內部創建了HandlerThread和異步線程的Handler來進行耗時操作
  • 啓動方式和Service一樣
  • 在開啓IntentService時,會回調執行onHandleIntent方法(異步線程中執行,非UI線程)
  • 執行完成後會自動停止,不需要額外調用stopSelf()。
  • 可以多次啓動IntentService,不會有多個實例,只會多次回調onHandleIntent方法。

2. IntentService的使用方法

  1. 繼承IntentService,複寫構造方法和onHandleIntent方法

    public class MyIntentService extends IntentService{
        /**
         * Creates an IntentService.  Invoked by your subclass's constructor.
         *
         * @param name Used to name the worker thread, important only for debugging.
         */
        public MyIntentService(String name) {
            super(name);
        }
    
        @Override
        protected void onHandleIntent(@Nullable Intent intent) {
            int arg = intent.getIntExtra("arg", 0);
            switch(arg){
                case 1:
                    //第一種情況處理
                    break;
                case 2:
                    //第二種情況處理
                    break;
                case 0:
                    //第三種情況處理
                    break;
            }
        }
    }
    
  2. 在manifest文件中註冊IntentService

    <service android:name=".intentservice.MyIntentService">
    </service>
    
  3. 通過startService啓動IntentService

    Intent i = new Intent(this,MyIntentService.class);
    i.putExtra("arg",2);
    startService(i);
    
  4. 借鑑一下個推的IntentService的onHandleIntent相關方法

    在onHandleIntent中處理各種不同的情況,然後使用工廠方法模式,讓子類實現那些未實現的接口,來執行不同的操作:接收消息的處理、設備是否在線的回調等。

        protected void onHandleIntent(Intent var1) {
        if(var1 != null) {
            try {
                this.processOnHandleIntent(var1);
            } catch (Throwable var3) {
                a.b("GTIntentService|" + var3.toString());
            }
    
        }
    }
    
    private void processOnHandleIntent(Intent var1) {
        Bundle var2 = var1.getExtras();
        if(var2 != null && var2.get("action") != null && var2.get("action") instanceof Integer) {
            switch(var2.getInt("action")) {
            case 10001:
                this.onReceiveMessageData(this, (GTTransmitMessage)var1.getSerializableExtra("transmit_data"));
                break;
            case 10002:
                this.onReceiveClientId(this, var2.getString("clientid"));
            case 10003:
            case 10004:
            case 10005:
            case 10006:
            case 10009:
            default:
                break;
            case 10007:
                this.onReceiveOnlineState(this, var2.getBoolean("onlineState"));
                break;
            case 10008:
                this.onReceiveServicePid(this, var2.getInt("pid"));
                break;
            case 10010:
                this.onReceiveCommandResult(this, (GTCmdMessage)var1.getSerializableExtra("cmd_msg"));
            }
    
        }
    }
    

3. IntentService源碼解析

  1. onStart方法

    這裏是標準的HandlerThread的標準用法,先創建HandlerThread實例,調用start()開啓線程。使用HandlerThread中的looper綁定工作線程的Handler。

    public void onCreate() {
    // TODO: It would be nice to have an option to hold a partial wakelock
    // during processing, and to have a static startService(Context, Intent)
    // method that would launch the service & hand off a wakelock.
    
    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();
    
    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
    

    }

  2. onStart

    在onStart中,調用工作線程的Handler發送消息到消息隊列。

    public void onStart(@Nullable Intent intent, int startId) {
        Message msg = mServiceHandler.obtainMessage();
        msg.arg1 = startId;
        msg.obj = intent;
        mServiceHandler.sendMessage(msg);
    }
    
  3. 工作線程的Handler

    工作線程的Handler中調用了onHandleIntent方法,onHandleIntent由子類實現,執行耗時操作。最後再執行stopSelf(msg.arg1),此處表示,把消息隊列中的消息處理完成後再停止。

    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);
        }
    }
    
  4. onBind

    不能通過onBindService的方式啓動IntentService,回調不到onHandleIntent

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

4. 幾種異步框架對比

IntentService: 進程優先級高,屬於後臺服務
其他異步線程需要綁定前臺線程,進程優先級低。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章