Service三问

时间:2022-07-26
本文章向大家介绍Service三问,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

作为Android四大组件之一,Service是一个可以后台运行的组件,执行长时间运行且不需要用户交互的任务。今天的三问就是关于Service:

  • Service生命周期
  • 两种启动方式及区别,Service与Thread的区别
  • 怎么保证Service不被杀死

Service生命周期

  • startService

生命周期:onCreate() -> onStartCommand() -> onDestory()

启动服务:onCreate() -> onStartCommand()

多次启动服务:会重复执行onStartCommand()

停止服务(stopService()):onDestory()

  • bindService

生命周期:onCreate() -> onBind() -> onUnbind() -> onDestory()

绑定服务:onCreate() -> onBind()

解绑服务:onUnbind() -> onDestory()

两种启动方式及区别,Service与Thread的区别

1)两种启动方式及区别

  • 第一种方式是通过在Manifest.xml里面配置Service,然后使用Context的startService(Intent)方法启动该Service。这种方式是一旦服务启动,就和启动者没什么关系了,就算启动者(比如activity)退出了,服务还是长期运行的。
  • 第二种方式是通过在Manifest.xml里面配置Service,然后调用Context的bindService(Intent, ServiceConnection, int)方法启动该Service,并且要记住使用unbindService(ServiceConnection)方法停止该服务。这种方式是会绑定到启动者的生命周期,如果启动者被销毁,服务也会被销毁。同时这种方法启动的服务是可以跟启动者进行通信的,onBind方法会返回一个IBinder对象,然后通过这个对象可以和服务进行通信。

2)Service与Thread的区别 这两者其实没有什么联系,之所以放在一起比较,主要是因为都是可以进行一些"偷偷进行"的工作,Service是可以在后台工作,而线程是可以在另外一条线路上工作。

  • Thread是程序运行的最小单位,如果单开线程是可以进行异步耗时工作的,就避免了在主线程进行耗时操作
  • Service是可以进行后台工作的,执行长时间运行且不需要用户交互的任务。但是其实它还是运行在主线程上面的,不管是当前进程还是单开一个进程,都是运行在主线程之上,所以其实是不能进行耗时操作的,如果要进行耗时操作还是要新建线程等,或者使用intentService

怎么保证Service不被杀死

  • onStartCommand方式中,返回START_STICKYSTART_STICKY表示的意思是如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service。另外还有一个值START_REDELIVER_INTENT,表示的意思是如果服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入,这种就适合需要读取intent信息的Service。
  • 提高Service的优先级,在在AndroidManifest.xml文件中对于intent-filter可以通过android:priority = "1000"这个属性设置最高优先级,1000是最高值,如果数字越小则优先级越低,同时适用于广播。
  • 提升Service进程的优先级,由于前台服务比后台服务拥有更高的优先级,也就是说系统会优先杀死后台服务。所以通过startForeground将service放到前台状态,就会减少被杀死的概率
  • 在onDestroy方法里重启Service。当service走到onDestroy()时,发送一个自定义广播,当收到广播时,重新启动service。
  • 双进程保活,开启两个进程的Service,然后在onStartCommand方法里面去分别绑定另一个Service,当另一个Service被销毁的时候就去启动它。
  • 使用JobService或者WorkManager,定时循环某个服务是否还存活,如果被销毁了就去启动。
  • 将APK安装到/system/app,变身为系统级应用(几乎不可能,除非是定制系统)