清晰地理解Service
问题1. Service的start和bind状态有什么区别?
- unbind只能解绑一次,否则会抛出异常,stopService可以一直Stop
- startService 每次调用都会触发onStartCommand ,只有第一次服务创建的时候触发onCreate,bindService,只触发一次onBind
- start启动的service,service有独立的生命周期,不依赖调用的组件,bind依赖调用的组件,调用 组件销毁后,服务也停止.
- intentSerivice 会自己调用stopSelf方法,内部使用的是HandlerThread
问题2. 同一个Service,先startService再bindService,如何把它停掉?
先startService再bindService,必须调用 unbindService和stopService 才能完全退出Service
bindService 如果是不同的ServiceConnection,需要多次解绑,如果是相同的只需要解绑1次
问题3. 你有注意到Service的onStartCommand方法的返回值吗?不同的返回值有什么区别?
/**
* 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.
*为了兼容版本,在Service被杀死后,并不保证onStartCommand会被再一次调用
*/
public static final int START_STICKY_COMPATIBILITY = 0;
/**
* 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.
*
*Service被杀死后,保留启动状态,但不保存intent,之后系统会重启service,并重新回
*调onStartCommand方法,如果接下来没有其他start命令,intent会为null,所以需要
*对Intent非空判断
*/
public static final int START_STICKY = 1;
/**
* 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.
*
* 常规操作,除非死之前还有组件调用StartService,否则系统不会保留启动状态并重
*启该Service
*/
public static final int START_NOT_STICKY = 2;
/**
* 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).
*
*Serivce被杀死后,系统会组织一次service重启(除非这之前调用了stopSelf()方法),
*被杀死前最后一次的传递Intent会重新执行,此falg保证了不会传递空Intent
*/
public static final int START_REDELIVER_INTENT = 3;
问题4. Service的生命周期方法onCreate,onStart,onBind等运行在哪个线程?
Service运行在主线程中,Service中进行耗时操作也会出现ANR(IntentService 内部实现是通过新建HandlerThread线程,然后把任务放到子线程里面去运行,可以认为是Service里面又新建了子线程 )
问题5. 扩充问题 Service与Thread 有什么关系?
Service和Thread之间没有任何关系,Service的后台概念是指可以脱离UI运行,即使Activity被销毁,或者程序被关闭,只要进程还在,Service就可以继续运行.Service是运行在主线程中的,也会引起ANR.
当Activity被销毁之后,就没有任何其它的办法可以再重新获取到之前创建的子线程的实例。而且在一个Activity中创建的子线程,另一个Activity无法对其进行操作。但是Service就不同了,所有的Activity都可以与Service进行关联,然后可以很方便地操作其中的方法,即使Activity被销毁了,之后只要重新与Service建立关联,就又能够获取到原有的Service中Binder的实例。因此,使用Service来处理后台任务,Activity就可以放心地finish,完全不需要担心无法对后台任务进行控制的情况。
网友评论