Android四大組件之Service

前言

Service 算是四大組件中比較經常使用的吧,至少比起 Broadcase receiverContent provider 還算是用的多的,這裏用來記錄一些關於 Service 的小細節。java

startServicebindService 所致使的生命週期

定義一個 Service 跟一個 Activity ,分別以下:算法

public class MainActivity extends AppCompatActivity {

    private Intent mIntent;
    private MyServiceConnection mMyServiceConnection;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMyServiceConnection = new MyServiceConnection();
        mIntent = new Intent(this, MyService.class);
    }

    public void startService(View view) {
        startService(mIntent);
    }
    public void unbindService(View view) {
        unbindService(mMyServiceConnection);
    }
    public void bingService(View view) {
        bindService(mIntent, mMyServiceConnection, BIND_AUTO_CREATE);
    }
    public void stopService(View view) {
        stopService(mIntent);
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.e("jiang", "onDestroy");
    }
    class MyServiceConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.e("jiang", "onServiceConnected:");
            MyService.MyBinder myBinder = (MyService.MyBinder) service;
            myBinder.systemOut();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e("jiang", "onServiceDisconnected:");
        }
    }
}
public class MyService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.e("jiang", "onCreate");
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.e("jiang", "onBind");
        return new MyBinder();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e("jiang", "onStartCommand: flags :" + flags + "   startId  :" + startId);
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void unbindService(ServiceConnection conn) {
        super.unbindService(conn);
        Log.e("jiang", "unbindService");
    }
    @Override
    public boolean onUnbind(Intent intent) {
        Log.e("jiang", "onUnbind");
        return super.onUnbind(intent);
    }
    @Override
    public void onDestroy() {
        Log.e("jiang", "onDestroy");
        super.onDestroy();
    }
    class MyBinder extends Binder {
        public void systemOut() {
            Log.e("jiang", "該方法在MyService的內部類MyBinder中");
        }
    }
}
  • (1)、 startService 所走的生命週期:ide

    onCreate
    onStartCommand: flags :0   startId  :1

    (2)、stopService 所走的生命週期:this

    onDestroy
  • (1)、bindService 所走的生命週期:spa

    onCreate
    onBind
    onServiceConnected:
    該方法在MyService的內部類MyBinder中

    (2)、unDindService 所走的生命週期:.net

    onUnbind
    onDestroy
  • (1)、 startService 所走的生命週期:code

    onCreate
    onStartCommand: flags :0   startId  :1

    (2)、bindService 所走的生命週期:blog

    onBind
    onServiceConnected:
    該方法在MyService的內部類MyBinder中

    (3)、stopService 所走的生命週期:生命週期

    什麼也不走進程

    (4)、unBindService 所走的生命週期:

    onUnbind
  • (1)、 startService 所走的生命週期:

    onCreate
    onStartCommand: flags :0   startId  :1

    (2)、bindService 所走的生命週期:

    onBind
    onServiceConnected:
    該方法在MyService的內部類MyBinder中

    (3)、unBindService 所走的生命週期:

    onUnbind

    (4)、stopService 所走的生命週期:

    onDestroy
  • (1)、 bindService 所走的生命週期:

    onCreate
    onBind
    onServiceConnected:
    該方法在MyService的內部類MyBinder中

    (2)、startService 所走的生命週期:

    onStartCommand: flags :0   startId  :1

    (3)、stopService 所走的生命週期:

    什麼也不走

    (4)、unBindService 所走的生命週期:**

    onUnbind
    onDestroy
  • (1)、 bindService 所走的生命週期:

    onCreate
    onBind
    onServiceConnected:
    該方法在MyService的內部類MyBinder中

    (2)、startService 所走的生命週期:

    onStartCommand: flags :0   startId  :1

    (3)、unBindService 所走的生命週期:

    onUnbind

    (4)、stopService 所走的生命週期:

    onDestroy

若是 Service 被屢次 start ,會屢次調用 onStartCommand ,並會給 onStartCommand 參數 startId 傳遞調用的次數。

屢次調用 unbindService 會報 java.lang.IllegalArgumentException: Service not registered: 異常,可是屢次 bindService 就沒有任何問題。

若是咱們採用的是 startService 開啓一個 Service ,在 Activity 關閉後,Service 依舊運行在系統中。

若是咱們採用的是 bindService 開啓一個 Service ,在 Activity 關閉時也會銷燬 Service ,就算你沒有調用 unBindService 方法。

若是咱們 start 而且 bind 一個 Service ,怎麼樣才能夠銷燬這個 Service 呢?有如下幾種方法:

  • 調用 stopServiceunbindService 這兩個方法,調用順序不分前後。
  • 先調用 stopService ,而後再關閉 Activity

Service的 onStartCommand 方法的返回值

通常來講,咱們重寫 ServiceonStartCommand 方法都會返回 super.onStartCommand(intent, flags, startId) ,但這個默認的返回值是啥呢?咱們一塊兒到 Service 的源碼中看看:

public @StartResult int onStartCommand(Intent intent, @StartArgFlags int flags, int startId) {
    onStart(intent, startId);
    return mStartCompatibility ? START_STICKY_COMPATIBILITY : START_STICKY;
}

經過 mStartCompatibility 進行三元運算法,從而返回不一樣的值,mStartCompatibility 其實表示的就是應用的 targetSdkVersion 是否小於5。對於如今的 APP 來講,targetSdkVersion 早就大於5了,因此 mStartCompatibility 天然就爲 false ,而 super.onStartCommand(intent, flags, startId) 返回的就是 START_STICKY

那麼這個返回值又有什麼用呢?說實話,我寫代碼來驗證這個返回值貌似並很差使,也就是說不像註釋說的那樣牛逼,有時候會失效,甚至能夠說是大部分都在失效。咱們這裏就來解讀一下注釋上所描述的返回值的做用:

  • START_STICKY_COMPATIBILITY :與 START_STICKY 效果相同,主要是爲了兼容低版本,可是並不能保證每次都重啓成功。
  • START_STICKY :進程被殺死之後,服務會自動重啓,並調用 onStartCommand 方法,可是並不會保存 intent ,因此須要在 onStartCommand 處理 intent 的話,記得要判空。可是 startId 會+1。
  • START_NOT_STICKY :進程被殺死之後,服務並不會自動重啓,就算是從新啓動 App 也會不重啓服務。
  • START_REDELIVER_INTENT :進程被殺死之後,服務會被自動重啓,onStartCommand 方法會被調用,可是 intent 不爲空,由於系統保存了上一次服務被殺死時的 intentstartId

onStartCommand 方法返回不一樣的返回值致使服務被殺死的時候自動重啓,這個重啓次數只能是一次。好比說服務被殺死一次之後,由於 onStartCommand 方法的返回值重啓了這個服務,可是又被殺死了,這個時候服務不會再次由於 onStartCommand 方法的返回值重啓服務了。

短期的服務被屢次殺死之後,系統就不肯意爲你再重啓這個服務了。

感謝

Android Service.onStartCommand() 方法
Service: onStartCommand 詭異的返回值
Android中Service類中onStartCommand返回值介紹

相關文章
相關標籤/搜索