一、StartService和BindService的区别
执行StartService时,Service的生命周期为onCreate,onStartCommand。使用StartService启动的Service只能通过调用StopService结束该Service。结束Service时,生命周期为onDestroy。
执行BindService时,Service的生命周期为onCreate,onBind。使用BindService启动的Service只能通过调用UnBindService结束该Service。结束Service时,生命周期为onUnbind,onDestroy。
二、同一个Service,先StartService,后BindService,如何把它停掉
由上述问题一可以知道,StartService只能通过StopService结束Service,而BindService只能通过UnBindService结束Service。所以,一个Service,先Start后Bind,需要执行StopService和BindService才能把这个Service停止掉。 也就是说需要执行StopService和BindService,Service才会执行onDestroy的生命周期。但是StopService和BindService执行的先后顺序可以不同。
三、Service的onStartCommand方法不同返回值的区别
Service的onStartCommand方法有三个返回值,分别是
-
START_STICKY 表示Service所在的进程被系统强制杀死后,系统会将该Service设置为started状态(运行状态),但是不再保存onStartCommand方法传入的Intent对象,然后系统会再次重新创建该Service,并执行onStartCommand方法,但是其中的Intent对象为null,也就是说onStartCommand方法虽然会执行,但是却获取不到Intent信息。
使用场景:如果Service在任意时刻运行或者结束都没什么问题,而且不需要Intent信息,那么就可以在onStartCommand方法中返回START_STICKY。例如一个用于播放背景音乐的播放器就适合返回该值。
-
START_NOT_STICK 表示当Service所在的进程被系统强制杀死后,系统不再重新创建该Service。如果想要重新实例化该Service,必须调用StartService来启动。
使用场景:在Service执行的过程中被中断或者由于内存紧张导致Service被回收并且无需立即重新创建,可以在返回值中使用该值。例如在Service中定时从服务器获取最新的数据。
-
START_REDELIVER_INTENT 表示Service所在的进程被系统强制杀死后,与START_STICKY的情况类似。这里会保存onStartCommand方法传入的Intent对象,然后系统会再次重新创建该Service,并执行onStartCommand方法。
使用场景:如果Service需要依赖具体的Intent对象(需要从Intent中获取相应的数据信息)才能运行,并且在强制销毁后有必要重新创建运行,那么这样的Service适合返回该值。
四、Service的生命周期方法onCreate、onStartCommand、onBind等运行在哪个线程中
Service生命周期方法onCreate、onStartCommand、onBind、onUnbind方法都运行在主线程。 我们可以在这几个方法中执行如下的代码:
Thread thread = Thread.currentThread();
Log.d("ABC", "onCommandStart。Thread.Id=" + thread.getId() + " ; Thread.name=" + thread.getName());
如上是在onStartCommand方法中执行打印当前线程信息的代码。得到的结果是onCommandStart。Thread.Id=1 ; Thread.name=main。从Thread.name=main可以知道onStartCommand方法是运行在主线程的。其他的方法以此执行得到的结论也是如此。