常见问题
1. 说说Service的两种启动方式及其生命周期。
可以通过Context.startService()和Context.bindService()两种方式启动Service。
在通过Context.startService()启动Service时,会依次调用Service的onCreate()→onStartCommand()方法,通过Context.stopService()或Service.stopSelf()停止Service后,会调用onDestory()方法。
在通过Context.bindService()启动Service()时,会依次调用Service的onCreate()→onBind()方法,在通过Context.unbindService()解除绑定或Service所绑定的Context不存在时,Service会被终止,此时会调用onDestory()方法。
在启动Service时,无论startService()执行多少次,系统都只会创建一个Service实例。onCreate()方法也只会被调用一次,但onStartCommand()方法每次都会被调用,终止Service时,也只需要调用一次stopService()或stopSelf()。
同理,在启动Service时,无论bindService()执行多少次,系统都只会创建一个Service实例。onCreate()方法也只会被调用一次,但bindService()方法每次都会被调用,终止Service时,也只需要调用一次unbindService()。
2. startService()与bindService()有什么区别?
1.1 Context.startService()启动Service后,Context与Service无关联,Service独立于Context在后台运行,直到被终止[stopService() / stopSelf()]或被系统强制回收。
1.2 Context.bindService启动Service后,Service与Context便形成绑定关系,除了调用unbindService()解除绑定会导致Service终止,启动Service的Context被终止,也会导致绑定的Service被终止。
2.1 startService()启动Service时,对应onStartCommand(),终止Service时,对应stopService()或stopSelf()。
2.2 bindService启动Service时,对应的是onBind(),终止Service时,对应的是unbindService()。
3.1 Context.startService启动的Service,无法直接与Context进行交互,可以通过BroadcastReceiver或EventBus进行交互。
3.2 Context.bindService启动的Service,可以通过ServiceConnection(Binder)实现Context与Service间的交互。
3. 如果一个Service即被startService()又被bindService(),生命周期是怎样的?
startService()和bindService()可以同时启动同一Service,执行时会回调对应的onStartCommand()或onBind(),但onCreate()只会被执行一次,不会被重复执行。
在停止
Service
时,即需要调用stopService()
,又需要调用unbindService()
,没有先后顺序要求,只有两个方法都执行完毕后,才会执行Service
的onDestroy()
,onDestroy()
只会被执行一次。
4. 如何保证Service不被杀死?
在
onStartCommand()
方法中返回START_STICKY
。这种情况下,当内存不足需要回收该Service时,系统会将该Service标记为started
状态,并在合适的时机重新调用onStartCommand()
重启该Service,这种情况下不会保留onStartCommand()
方法中的intent
对象(intent对象为null)。如需在重启Service时保留onStartCommand()
中的intent
对象,可以返回START_REDELIVER_INTENT
,此时则会保留intent
最近一次的值,并传入到onStartCommand()
方法中。提高该Service在所有Service中的优先级。可以在AndroidManifest.xml中为每一个Service配置一个优先级,数值越大,优先级越高。如:
<service> <intent-filter android:priority="1000"/></service>
将Service设置为前台Service,Service默认在后台运行,但调用Service.startForeground()即可将将该Service设置为前台Service,从而提高该Service的进程优先级。当系统的进程空间紧张时,会按照进程优先级依次回收,Android系统的进程优先级如下:
(1) 前台进程(foreground_app)
(2) 可见进程(visible_app)
(3) 次要服务进程(secondary_server)
(4) 后台进程(hidden_app)
(5) 内容提供者进程(content_provider)
(6) 空进程(empty_app)在Service的onDestroy()方法里发送一个自定义广播,在广播的onReceiver()内重新启动该Service。
监听开机广播,开机时自动启动Service。
网友评论