Service

Service主要在后台执行耗时操作,或者为其他进程提供服务。Service运行在主线程之中,如果要执行耗时操作,还得创建一个线程; 所以如果单单是为了将耗时操作挪出主线程,可以创建线程,如果是想用户不再和app交互时仍可在后台运行可以创建service。


1. Service可以分为三类
  • Foreground
    前台service是指那些执行可以被用户觉察到操作的service;前台service会弹出Notification(只能是Status bar notification?),即使用户没有和对应的app交互,前台service也依然会运行。

  • Background
    后台service是指那些执行不能别用户直接觉察到操作的service。从Android 8.0开始对这种service增加了限制, 什么限制?限制后台的应用创建/使用Background service; 如果应用想创建foreground service,可以调用startForegroundService()方法,这个方法会创建一个background service,但是这个方法会向系统发消息该service将会成为foreground service; 一旦service被创建,其必须在5秒内调用startForeground() 方法。

  • Bound
    被其他component使用bindSerivce()方法bind的service就是Bound service。这种service为client-server提供了接口,通过这个接口client可以和service交互; Bound service的生命周期由bind它的组件决定(unbind后就被销毁了)。


2. Service启动的两种方式
  • 通过调用startService()
  • 通过调用bindService()

Service_第1张图片
左侧是使用startService() 方法创建的service的生命周期。
右侧是使用bindService() 方法创建的service的生命周期。

通过startService()来创建service,系统会回调onStartCommand() 方法,onStartCommand()会调用onStart()方法,然后service会一直运行下去。如果要终止service需要显式的调用stopself()或者其他组件调用stopService()方法,service终止后,系统会销毁它。

通过bindServie()创建service,系统会回调onBind() 方法,该方法应该返回一个IBinder对象,以便客户端和service交互。如果不允许service被bind,那么可以返回null。可以通过调用unbindService()方法 关闭与service的连接,多个组件(客户端)可以同时绑定到一个service,当所有的绑定连接都关闭时,系统就销毁该service。不需要显示的销毁,不需要管理生命周期。

但是这两种启动方式不是独立的,一个通过startService()方法创建的service也可以被bind, 而且bind后,通过调用stopself()或者stopService()并不能销毁该service。一个通过bindService()方法创建的service,其他组件也可以使用startService()方法去启动它,该service的onStartCommand()方法会被调用,但是onCreate()方法不会再次被调用。

不管通过那种方式创建的service,都会调用onCreate()和onDestroy()方法。onCreate()在service被创建时调用,onDestroy()在service销毁时调用,这两个方法都只会执行一次。
每次通过startService/bindService启动service时,相应的onStartCommand()/onBind()方法都会被调用。

Service的生命时间(active lifetime)是从onStartCommand() 或onBind()被调用开始,它们各自处理由startService()或 bindService()方法传过来的Intent对象。通过startService()方式启动的service的active lifetime会在整个生命周期结束时结束; 通过bindService()方式启动的service的active lifetime会在onUnbind()方法结束时结束。


3. Service生命周期的管理

通过startService()方式创建的service需要调用stopself()或者stopService(),不论是否被bind。
纯粹通过bindService()创建的service不需要管理生命周期。
如果Service的onStartCommand()方法和onBind()方法都被调用(无论顺序),那么这个service的生命周期如下图:
Service_第2张图片
如果一个servie启动并且接收了bind,当系统调用onUnbind()时可以返回true,这样客户端下次bind service时onRebind会被调用;onRebind返回值为void,但是仍然可以在onServiceConnected()回调方法中得到 IBinder接口实例。


4. 系统force-stop

当内存紧张,系统需要释放内存资源的时候,系统会强制停止service(force-stop)。
如果service和拥有用户焦点的activity绑定在一起,那么这个service不太可能被stop。
如果service是foreground service,那么被stop的可能性也不大。
如果service被started并且长时间运行,那么系统会降低其在后台任务中的优先级,那么很可能会被stop; 针对这种情况,如果该service的onStartCommand()方法返回的是START_STICKY/
START_REDELIVER_INTENT,那么系统会在系统资源充足时重新启动被stop的service。


5. 实现自己的Service类

要实现自己的Service,继承Service类就好。
Service生命周期回调函数和Activity不一样,实现自己的service类时,不需要调用那些回调函数的父类实现。


结束!

你可能感兴趣的:(android)