#Android 学习计划#
#第二周#
1、Service的start和bind状态有什么区别?
start 是启动状态,主要用于执行后台计算。
该状态下 Service 有独立的生命周期,不依赖于启动它的组件。bind 是绑定状态,主要用于其他组件和 Service 的交互。
该状态下 Service 依赖于启动它的组件,当这些组件全部销毁后,Service 随即销毁。
2、同一个Service,先startService,然后再bindService,如何把它停止掉?
无论调用多少次 startService 和 bindService,只需调用一次 stopService 和 unbindService 即可停止该 Service,调用顺序无要求。
最后一次 stopService / unbindService 调用会导致 Service#onDestroy 的执行。
3、你有注意到Service的onStartCommand方法的返回值吗?不同返回值有什么区别?
摘自源码注释:
* @return The return value indicates what semantics the system should
* use for the service's current started state. It may be one of the
* constants associated with the {@link #START_CONTINUATION_MASK} bits.
onStartCommand 方法返回该 Service 当前的开始状态。
一共有以下几种返回值:
/**
* Constant to return from {@link #onStartCommand}: compatibility
* version of {@link #START_STICKY} that does not guarantee that
* {@link #onStartCommand} will be called again after being killed.
*/
public static final int START_STICKY_COMPATIBILITY = 0;
START_STICKY_COMPATIBILITY
为了兼容版本,在 Service 被杀死后,不保证 onStartCommand 再次执行。
/**
* Constant to return from {@link #onStartCommand}: if this service's
* process is killed while it is started (after returning from
* {@link #onStartCommand}), then leave it in the started state but
* don't retain this delivered intent. Later the system will try to
* re-create the service. Because it is in the started state, it will
* guarantee to call {@link #onStartCommand} after creating the new
* service instance; if there are not any pending start commands to be
* delivered to the service, it will be called with a null intent
* object, so you must take care to check for this.
*
* <p>This mode makes sense for things that will be explicitly started
* and stopped to run for arbitrary periods of time, such as a service
* performing background music playback.
*/
public static final int START_STICKY = 1;
START_STICKY
在 Service 被杀死后,保留开始状态,但不保存 intent。稍后系统会重新创建该 Service。由于目前还处于开始状态,在创建新的 Service 实例后,会保证 onStartCommand 再次执行。如果接下来没有其他 onStartCommand 的执行,intent 会为 null,因此要注意对 intent 的判空。
使用场景:后台音乐重放。
/**
* Constant to return from {@link #onStartCommand}: if this service's
* process is killed while it is started (after returning from
* {@link #onStartCommand}), and there are no new start intents to
* deliver to it, then take the service out of the started state and
* don't recreate until a future explicit call to
* {@link Context#startService Context.startService(Intent)}. The
* service will not receive a {@link #onStartCommand(Intent, int, int)}
* call with a null Intent because it will not be re-started if there
* are no pending Intents to deliver.
*
* <p>This mode makes sense for things that want to do some work as a
* result of being started, but can be stopped when under memory pressure
* and will explicit start themselves again later to do more work. An
* example of such a service would be one that polls for data from
* a server: it could schedule an alarm to poll every N minutes by having
* the alarm start its service. When its {@link #onStartCommand} is
* called from the alarm, it schedules a new alarm for N minutes later,
* and spawns a thread to do its networking. If its process is killed
* while doing that check, the service will not be restarted until the
* alarm goes off.
*/
public static final int START_NOT_STICKY = 2;
START_NOT_STICKY
在 Service 被杀死后,如果没有其他 onStartCommand 的执行,不保留开始状态,不会重新创建该 Service。
使用场景:可以在内存紧张时销毁的服务,如每隔 N 分钟执行的下载任务。
/**
* Constant to return from {@link #onStartCommand}: if this service's
* process is killed while it is started (after returning from
* {@link #onStartCommand}), then it will be scheduled for a restart
* and the last delivered Intent re-delivered to it again via
* {@link #onStartCommand}. This Intent will remain scheduled for
* redelivery until the service calls {@link #stopSelf(int)} with the
* start ID provided to {@link #onStartCommand}. The
* service will not receive a {@link #onStartCommand(Intent, int, int)}
* call with a null Intent because it will will only be re-started if
* it is not finished processing all Intents sent to it (and any such
* pending events will be delivered at the point of restart).
*/
public static final int START_REDELIVER_INTENT = 3;
START_REDELIVER_INTENT
在 Service 被杀死后,如果所有的 intent 还没被处理完,则最后一次传递的 intent 将重新被执行(除非在那之前系统调用 Service#stopSelf(int))。
4、Service的生命周期方法onCreate、onStart、onBind等运行在哪个线程?
onCreate、onStart、onBind 均运行在主线程。
如果想要在 Service 中执行耗时操作,需手动开启子线程(或使用 IntentService),否则容易出现 ANR(20秒)。