Android_Services基础知识
生命周期:
-
OnCreate()
系统在 Service 第一次创建时执行此方法,来执行只运行一次的初始化工作,如果 Service 已经运行,这个方法不会被调用。
-
onStartCommand()
每次客户端调用 startService() 方法启动该 Service 都会回调该方法(多次调用),一旦这个方法执行,Service 就启动并且在后台长期运行,通过调用 stopSelf() 或 stopService() 来停止服务。
-
OnBind()
当组件调用 bindService() 想要绑定到 Service 时(比如想要执行进程间通讯),系统调用此方法(一次调用,一旦绑定后,下次再调用 bindService() 不会回调该方法)。
-
OnUnbind()
当前组件调用 unbindService() 解除与 Service 的绑定时,系统调用此方法(一次调用,一旦解除绑定后,下次再调用 unbindService() 会抛出异常)。
-
OnDestory()
系统在 Service 不再被使用并要销毁时调用此方法(一次调用),Service 应在此方法中释放资源,比如线程,已注册的侦听器,接收器等等,这是 Service 收到的最后一个调用。
三种不同情况下 Service 的生命周期情况
-
startService / stopService
生命周期顺序:onCreate -> onStartCommand -> onDestroy
如果一个 Service 被某个 Activity 调用 Context.startService() 方法启动,那么不管是否有 Activity 使用 bindService() 绑定或 unbindService() 解除绑定到该 Service,该 Service 都在后台运行,直到被调用stopService(),或自身的 stopSelf() 方法。
-
bindService / unbindService
生命周期顺序:onCreate -> onBind -> onUnBind -> onDestroy
如果一个 Service 在某个 Activity 中被调用 bindService 方法启动,不论 bindService 被调用几次,Service 的 onCreate 方法只会执行一次,同时 onStartCommand 方法始终不会调用。
当建立连接后,Service 会一直运行,除非调用 unbindService 来接触绑定、断开连接或调用该 Service 的Context不存在了(如 Activity 被终止)。
-
混合型(上面两种方式的交互,被启动又被绑定)
当一个 Service 在被启动(startService)的同时又被绑定(bindService),该 Service 将会一直在后台运行,并且不管调用几次,onCreate 方法始终只会调用一次。
同时,调用 unBindService 将不会停止 Service,必须调用 stopService 或 Service 自身的 stopSelf 来停止服务。
与activity的交互:
Activity 怎么和 Service 绑定?怎么在 Activity 中启动自己对应的 Service?
Activity 通过 bindService(Intent service, ServiceConnection conn, int flags) 跟 Service 进行绑定,当绑定成功的时候, Service 会将代理对象通过回调的形式传给 conn,这样就拿到了 Service 提供的服务代理对象。
Service 与 Activity 之间怎么通信?
Android 中,Activity 主要负责前台页面的展示,Service 主要负责需要长期运行的任务,所以在实际开发中,常常遇到 Activity 与 Service 之间的通信,以下两种方式可用来实现 Service 与 Activity 之间的通信问题:
- Activity 调用 bindService (Intent service, ServiceConnection conn, int flags)方法,得到 Service 对象的一个引用,这样 Activity 可以直接调用到 Service 中的方法,如果要主动通知 Activity,我们可以利用回调接口;
- Service 向 Activity 发送消息,可以使用广播(Broadcast),这需要 Activity 注册相应的接收器,接收到广播之后更新 ProgressBar。如果 Service 要向多个 Activity 发送同样的消息的话,用这种方法就更好。
说一说 Activity、Intent、Service 之间有什么关系?
Activity、Intent、Service 都是 Android 开发中使用频率最高的类。其中 Activity 和 Service 都是 Android 四大组件之一,都是 Context 类的子类 ContextWrapper 的子类。Activity 负责用户界面的显示和交互,Service 负责后台任务的处理,Activity 和 Service 之间可以通过 Intent 传递数据。
性能优化
如何保证 Service 不被杀死?
保证 Android 进程不死可从以下 3 个层面入手:
- 提高进程优先级,降低进程被杀死的概率:
- 方法一:监控手机锁屏解锁事件,在锁屏时启动 1 个像素的 Activity,在用户解锁时将 Activity 销毁掉;
- 方法二:启动前台 Service;
- 方法三:提升 Service 优先级。
- 在进程被杀死后,进行拉活:
- 方法一:注册高频率广播接收器,唤起进程,如网络变化,解锁屏幕,开机等;
- 方法二:双进程相互唤起;
- 方法三:依靠系统唤起;
- 方法四:onDestroy() 方法里重启 Service:Service + Broadcast 方式,就是当 Service 走 ondestory 的时候,发送一个自定义的广播,当收到广播的时候,重新启动 Service;
- 依靠第三方:根据终端不同,在小米手机(包括 MIUI )接入小米推送、华为手机接入华为推送,其他手机可以考虑接入腾讯信鸽或极光推送与小米推送做 A/B Test。
是否能在 Service 执行耗时操作?如果非要进行操作可以怎么做?
Service 是存在于主线程的,而耗时操作(例如网络请求、拷贝数据等)会阻塞主线程,给用户不好的体验,所以不可以在 Service 执行耗时操作。
如果要进行耗时操作,可以开辟一个子线程进行,例如选择 IntentService,IntentService 是 Service 的子类,用来处理异步请求。
前台服务是什么?和普通服务的区别在哪儿?如何去开启一个前台服务?
前台服务和普通服务最大的区别是,前者会一直在系统的状态栏显示一个正在运行的图标,下拉状态栏后可以看到更加详细的信息,非常类似于通知的效果。使用前台服务或者为了防止服务被回收掉,比如听歌,或者由于特殊的需求,比如实时天气状况。
要想开启一个前台服务,注意在构建好一个 Notification 之后,不需要 NotificationManager 将通知显示出来,而是调用 startForeground() 方法。
要想开启一个前台服务,注意在构建好一个 Notification 之后,不需要 NotificationManager 将通知显示出来,而是调用 startForeground() 方法。