1. Service 的 start 和 bind 状态有什么区别?
-
startService
Service 生命周期会经历onCreate--onStartCommand,调用stopService会调用onDestroy方法。如果没有调用stopService方法,Service会一直在后台存活,此时调用startService,会调用onStartCommand方法。 -
bindService
在bind的时候,会调用onCreate---onBind。这个时候调用者和Service绑定在一起。调用者调用unbindService方法或者调用者Context不存在了(如Activity被finish了),Service就会调用onUnbind->onDestroy。可以理解为两者共存亡。
2.同一个 Service,先 startService,然后再 bindService,如何把它停止掉?
其实这种情况下,单使用unbindService或者stopService是不管用的。
因为在bindService不调用unbindService或者调用者销毁,Service不会销毁,同样只调用stopService,这时候还存在绑定关系,那么Service也不会销毁。最好的办法是unbindService 然后stopService。
3.Service 的 onStartCommand 方法的返回值?不同返回值有什么区别?
conStartCommand方法主要用途在于决定当服务被杀死之后,要如何处理的问题。
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
在2.0 API level之后,实现onStart等同于重写onStartCommand并返回START_STICKY
onStartCommand使用时,返回的是一个(int)整形。 这里有四个返回值:START_STICKY、START_NO_STUCKY、START_REDELIVER_INTENT、START_STICKY_COMPATIBILITY
- START_STICKY:
如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。 - START_NOT_STICKY
“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务 - START_REDELIVER_INTENT
重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。 - START_STICKY_COMPATIBILITY
START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
flags含义
flags表示启动服务方式 - START_FLAG_REDELIVERY
如果你实现onStartCommand()来安排异步工作或者在另一个线程中工作, 那么你可能需要使用START_FLAG_REDELIVERY来让系统重新发送一个intent。这样如果你的服务在处理它的时候被Kill掉, Intent不会丢失. - START_FLAG_RETRY
表示服务之前被设为START_STICKY,则会被传入这个标记。
4.Service 的生命周期方法 onCreate、onStart、onBind 等运行在哪个线程?
都是在主线程。
public void onCreate() {
super.onCreate();
if (Looper.myLooper() == Looper.getMainLooper()) {
Log.e(TAG, "onCreate: UIMain ");
}
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
if (Looper.myLooper() == Looper.getMainLooper()) {
Log.e(TAG, "onStart: UIMain");
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
if (Looper.myLooper() == Looper.getMainLooper()) {
Log.e(TAG, "onBind: UIMain");
}
return null;
}
image.png
网友评论