前言Service 算是四大组件中比较常用的吧,至少比起 Broadcase receiver 跟 Content provider 还算是用的多的,这里用来记录一些关于 Service 的小细节。<!–more–>startService 跟 bindService 所导致的生命周期定义一个 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 所走的生命周期:onCreateonStartCommand: flags :0 startId :1(2)、stopService 所走的生命周期:onDestroy(1)、bindService 所走的生命周期:onCreateonBindonServiceConnected:该方法在MyService的内部类MyBinder中(2)、unDindService 所走的生命周期:onUnbindonDestroy(1)、 startService 所走的生命周期:onCreateonStartCommand: flags :0 startId :1(2)、bindService 所走的生命周期:onBindonServiceConnected:该方法在MyService的内部类MyBinder中(3)、stopService 所走的生命周期:什么也不走(4)、unBindService 所走的生命周期:onUnbind(1)、 startService 所走的生命周期:onCreateonStartCommand: flags :0 startId :1(2)、bindService 所走的生命周期:onBindonServiceConnected:该方法在MyService的内部类MyBinder中(3)、unBindService 所走的生命周期:onUnbind(4)、stopService 所走的生命周期:onDestroy(1)、 bindService 所走的生命周期:onCreateonBindonServiceConnected:该方法在MyService的内部类MyBinder中(2)、startService 所走的生命周期:onStartCommand: flags :0 startId :1(3)、stopService 所走的生命周期:什么也不走(4)、unBindService 所走的生命周期:**onUnbindonDestroy(1)、 bindService 所走的生命周期:onCreateonBindonServiceConnected:该方法在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 呢?有以下几种方法:调用 stopService 和 unbindService 这两个方法,调用顺序不分先后。先调用 stopService ,然后再关闭 Activity 。Service的 onStartCommand 方法的返回值一般来说,我们重写 Service 的 onStartCommand 方法都会返回 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 不为空,因为系统保存了上一次服务被杀死时的 intent 跟 startId 。对 onStartCommand 方法返回不同的返回值导致服务被杀死的时候自动重启,这个重启次数只能是一次。比如说服务被杀死一次以后,因为 onStartCommand 方法的返回值重启了这个服务,但是又被杀死了,这个时候服务不会再次因为 onStartCommand 方法的返回值重启服务了。短时间的服务被多次杀死以后,系统就不愿意为你再重启这个服务了。感谢Android Service.onStartCommand() 方法Service: onStartCommand 诡异的返回值Android中Service类中onStartCommand返回值介绍