Service、进程的相关内容

简述

Service作为Android的四大组件之一,使用频率仅次于Activity,使用时需在manifest进行注册。

由于service运行在主线程,所以不能进行耗时操作需另起线程。

API

Android 5.0 后service禁止隐式启动,需指明启动者

启动方式

有两种:

  • start(无交互,默默的后台工作)
  • bind(有交互可用于进程间通讯IPC)

启动方式的不同会有不同的生命周期。

startService()启动的Service和启动者的生命周期无关,必须要显示调用stopService/stopSelf方法,才能停止该Service;

bindService()启动的Service和启动者的生命周期有关,当启动者销毁时,会自动解绑该Service。

同一service被多次使用的场景:

  • startService - startService
    第一次的startService会有onCreate()>onStartCommand()实例创建成功开始工作
    第二次的startService并不会创建新的实例,而是使用之前的实例并执行onStartCommand()
    当调用stopService()或任务执行完毕实例自己stopSelf()时onDestroy()执行,多次调用无效实例只有一个。

  • startService - bindService
    startService时实例创建onCreate()>onStartCommand()
    bindService时由于已存在实例,onBind()执行
    stopService()、stopSelf()由于实例还有引用所以不会触发任何方法
    unbindService()时触发onUnbind()此时实例没有引用紧接着onDestroy()
    bindService- startService 顺序反过来即可

  • bindService- bindService(绑定者不同情况,绑定者相同不会触发任何)
    第一次的bindService会有onCreate()>onBind()执行,此时实例创建
    第二次的bindService并没有触发onBind()(对于service而言已经绑过了,至于几次并不影响),但会返回IBinder给绑定者即onServiceConnected
    若绑定者unbindService此时service没有引用则调用onUnbind()>onDestroy(),若还有其他引用service不会被销毁
    若一绑定者多次调用unbindService则 java.lang.IllegalArgumentException: Service not registered:
    若调用者结束前没有调用unbindService,则会造成内存泄漏android.app.ServiceConnectionLeaked,警告过后系统会unbindService。

Service生命周期

onBind 返回 null 时不会回调 onServiceConnected
onServiceDisconnected异常断开才会回调

多进程

Android的四大组件都可以设置多进程,在manifest中设置android:process属性。

目的

  • 进程为资源分配的最小单元,一个应用多个进程则可以获取系统更多的资源。
  • 功能分离,界面交互、消息推送、APP心跳等可在不同进程中执行,一个进程杀掉后不会影响其他功能

实现

多进程分为两种:私有进程和全局进程。

私有进程

属性设置以“:”开头表示开启的新进程为当前进程所私有,不能够跨进程使用。

全局进程

属性设置以小写字母开头的进程为全局进程,可以被多个应用共用,详细内容会有进程间通讯篇。

缺点

  • 每开启一个进程的时候,Application就会执行一遍onCreate(),一般会在里面做一些初始化操作。多次执行必定会导致没有必要的各种浪费,所以需要在初始化的时候判断当前进程。(我的第一篇博文就是这个Android项目之Application,当时只知道这么写却没想这么深)

  • 数据共享问题
    多进程之间数据无法共享,需要进程间通讯。

  • SQLite容易被锁
    多进程操作数据库,可能会发生死锁。

保活

保活有两种方式:提高进程的优先级、多进程之间互相拉活

优先级

进程按优先级分为:前台进程、可见进程、服务进程、后台进程、空进程

  • 前台进程,当前用户操作所需要的进程
    1、用户正在交互的Activity(Activity执行了onResume方法)
    2、Service绑定到正在交互的Activity
    3、Service设置为前台(Service调用startForeground()方法)
    4、正在执行某些生命周期回调的Service,onCreate()、onStart()、onDestroy()
    5、正在执行onReceive()的BroadcastReceiver

这种进程基本不会被回收,只有当内存不足以支持前台进程同时运行的时候,系统才会回收它们,主要关注前三个。

  • 可见进程,没有与用户交互所必须的组件,但是在屏幕上仍然可见其内容的进程
    1、调用了onPause()方法但仍对用户可见的Activity
    2、绑定到上面这种Activity的Service

  • 服务进程
    1、使用startService()启动的Service且不属于上面两种类别的进程

虽然这个进程与用户交互没有直接关系,但是一般会在后台执行一些耗时操作,所以,只有当内存不足以维持所有前台进程和可见进程同时运行,系统才会回收这个类别的进程。

  • 后台进程,
    1、对用户不可见Activity进程,已调用了onStop()方法的Activity

  • 空进程,不包含任何活动应用组件的进程,保留这种进程唯一目的是作为缓存,缩短引用组件下次启动时间。通常系统会最优先回收这类进程。

通过提升进程的优先级,可以减少被系统回收的概率。方案有:

  • 一像素Activity
  • 前台service
  • 播放空音频(耗电)

拉活

多个进程之间互相监听,当发现其中一个进程被kill后其他进程将其再次启动(用户手动清除的,APP进程组全部被清,所以拉活仅限系统回收和多APP之间)。

方案(目前可行):

  • JobScheduler

你可能感兴趣的:(Service、进程的相关内容)