Service
Service是android系统中的四大组件之一,它跟anctivity的级别相似,但是没有自己的界面,只能在后台运行。可以和其他组建进行交互。
启动方式
Context.startService() started
模式
这种方法调用者和Service之间没有关联,即使调用者退出了,服务仍然运行。
Context.bindService() Bound
模式
这种方法调用者和Service绑定在了一起,调用者退出,服务也就终止。
生命周期
对于Service的不同启动方式,有着不同的生命周期
-
Context.startService()
context.startService() -->onCreate() -->onStart() -->Service running -->context.stopService() -->onDestroy() -->Service stop
如果Service还没有运行,则会运行onCreate()然后调用onStart()
如果Service已经运行,则只调用onStart。onStart可能被调用多次
可以通过stopService()停止Service -
Context.bindService()
context.bindService() -->onCreate() -->onBind() -->Service running -->onUnbind() -->onDestroy() -->Service stop
如果在服务未被创建时,系统会先调用onCreate()方法,接着调用onBind()方法。这个时候调用者和服务会绑定在一起,调用者退出了,系统就会先调用onUnbind()方法,接着调用onDestroy()方法。如果bindService()方法前服务已经被绑定,多次调用bindService()方法不会导致多次创建服务以及绑定。如果调用unbindService()方法,也会导致系统调用服务的onUnbind()和onDestroy()方法。
onBind()会返回给客户端一个IBind接口实例,IBind允许客户端回调Service的方法,比如得到Service的实例、运行状态等。这个时候把调用者会和Service绑定到一起,Context退出了,Service就会调用onUnbind–>onDestroy相应退出。
onBind()只有一次,不可以多次绑定
Service 的停止
Service.stopSelf()
只要调用一次stopService就可以停止Service,无论start多少次
Service.stopSelfResult()
被多次bind的Service如何关闭?
有三种情况:如果直接使用服务,则没有必要进行绑定,但是如果要使用服务里面的方法,则要进行绑定。具体的启动情况有下:
1.当启动时,单独调用bindService方法,再unbindService后,会执行service的onUnbind,在执行onDestroy方法。
2.当启动时,先调用startService,再调用bindService方法后,再unbindService后,会执行service的onUnbind,不会执行onDestroy方法。除非你在执行stopService.
3. 先调用startService,再调用stopService,会执行service的onDestroy方法。
AndroidManifest.xml 注册Service
<service
android:enabled="true"
android:name=".service.Service">
<intent-filter>
<action android:name="com.action.service" />
</intent-filter>
</service>
onStartCommand返回值
- START_NOT_STICKY
表示当Service运行的进程被Android系统强制杀掉之后,不会重新创建该Service,当然如果在其被杀掉之后一段时间又调用了startService,那么该Service又将被实例化。那什么情境下返回该值比较恰当呢?如果我们某个Service执行的工作被中断几次无关紧要或者对Android内存紧张的情况下需要被杀掉且不会立即重新创建这种行为也可接受,那么我们便可将 onStartCommand的返回值设置为START_NOT_STICKY。 - START_STICKY
表示Service运行的进程被Android系统强制杀掉之后,Android系统会将该Service依然设置为started状态(即运行状态),但是不再保存onStartCommand方法传入的intent对象,然后Android系统会尝试再次重新创建该Service,并执行onStartCommand回调方法,但是onStartCommand回调方法的Intent参数为null,也就是onStartCommand方法虽然会执行但是获取不到intent信息。如果你的Service可以在任意时刻运行或结束都没什么问题,而且不需要intent信息,那么就可以在onStartCommand方法中返回START_STICKY - START_REDELIVER_INTENT
表示Service运行的进程被Android系统强制杀掉之后,与返回START_STICKY的情况类似,Android系统会将再次重新创建该Service,并执行onStartCommand回调方法,但是不同的是,Android系统会再次将Service在被杀掉之前最后一次传入onStartCommand方法中的Intent再次保留下来并再次传入到重新创建后的Service的onStartCommand方法中,这样我们就能读取到intent参数。只要返回START_REDELIVER_INTENT,那么onStartCommand重的intent一定不是null
服务是否在运行
顺便提下怎样查看一项服务是否在运行的方法:
private String isRunning(Context context) {
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningServiceInfo> list = am.getRunningServices(30);
for (RunningServiceInfo info : list) {
if ((info.service.getClassName()).equals("com.fred.app.MyService")) {
return "running......";
}
}
return "stopped......";
}