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返回值介绍

相关文章
相关标签/搜索