zoukankan      html  css  js  c++  java
  • Android Service启动原理分析

    一、概述

      Service是Android的四大组件之一,我们可以利用它开启一个后台服务,Service的优先级比较高,一旦其在后台运行即使App处于后台则Service运行的任务也不容易被杀死。了解Service的工作原来除了可以加深对底层的Service机制的理解以外还可以为当前比较流行的热更新做服务(即Service的插件化)

      Service分为两种状态一种一种是启动状态,可以做一些后台的任务计算。一种是绑定状态,帮助Service和用户进行交互。

      1.启动状态的声明周期为:onCreate——onStartCommon——onDestory

      2.绑定状态的生命周期为:onCreate——onBind——onUnBind——onDestroy

      在启动状态下原理分为两部分:1.Service和目标App不在同一个进程。2.Service和App在同一个进程

      绑定状态下的原理分析也分为两个部分:1.Service和App不再同一个进程。2.Service和App在同一个进程

      其实不管是启动状态还是绑定状态的原理都和之前介绍的Activity的启动原理非常的相似,其实都是反反复复的和AMS交互(握手)的过程,然后利用PMS加载包信息,获取ClassLoader,并利用ClassLoader加载类并通过反射实例化的过程。

    二、原理分析

      先说下启动状态下App和Service不在同一个进程中的情况。这个过程分为五部,先说下原理然后再介绍调用栈。

      1.App通知AMS要启动一个Service,并把启动信息发送给Service

      2.AMS收到消息后保存信息,并检查service所在的进程是否已经启动了,如果已经启动了就直接打开,如果没有启动就启动一个新的进程

      3.App进程启动好以后通知AMS已经启动好了

      4.AMS收到App启动好的消息后就翻出保存在ServiceRecord中的信息,并把其发送给App

      5.App收到启动信息后启动Service即可

      上面所说的是一个大概的步骤,下面将详细说一下这五步的具体实现

      1.App调用context.startService方法,在Context.startService方法内部又会调用ActivityManagerNative.getDefault().startService方法,ActivityManagerNative.getDefault()返回的是一个IActivityManager接口,里面存储了四大组件的所有生命周期函数,而ActiivtyManagerProxy是AMS在App的代理对象,其也集成了IActivityManger接口。所以最终会是ActivityManagerProxy.startService把Service的信息发送给AMS

      2.AMS通过跨进程通信的方式收到Service的信息后会保存在ServiceRecord中,然后检查Service是否在AndroidManifest.xml中注册,如果没有注册则报错。检查service进程是否已经启动了,如果没有启动则会调用Process.start(android.app.ActivityThread)方法启动一个新的进程。

      3.App进程启动是会实例化ActivityThread对象并调用其中的main方法来开启进程,进程启动后会通过ActivityManagerProxy代理对象把ActivityThread对象发送给AMS

      4.AMS接收到ActivityThread对象后会把ActivityThread对象包装成为ApplicationThreadProxy对象(app的代理对象),并从ServiceRecord中翻出在第二步中保存的service信息,并通过ApplicationThreadProxy.scheduleCreateService将信息发送给App进程

      5.App进程通过ApplicationThread接收消息,并调用ActiivtyThread的sendMessage方法向H发送消息,在H的handleMessage方法会接收消息,之后会调用ActivityThead的handleCreateService方法通过packageinfo拿到加载类的classloader并通过反射创建Service对象,创建完service对象后会紧接着调用其onCreate函数来完成Service的启动。

      

      Service和App在同一个进程中的情况分为三步:

      1.app调用Context.startService方法,startService方法又会调用ActivityManagerProxy.startSerivce方法把intent消息发送给AMS

      2.AMS检查service是否在AndroidManifest.xml中注册,如果没有注册就抛异常,AMS检查Service所在的进程是否已经启动,如果启动了则将Service启动信息通过ApplicationThreadProxy.scheduleCreateService发送给App进程

      3.App进程通过ApplicationThread接收消息并通过ActivityThread.sendMessage发送消息,之后的过程就和上面的第5步是一样的。

      绑定过程原理描述:

      1.App通过Context.bindService发起绑定,最终会通过ActivityManagerProxy.bindService把service的Intent信息放给AMS

      2.AMS检查Service是否在AndroidManifest.xml中进行了注册,如果没有则抛异常。AMS会保存App进程传递过来的信息到ServiceRecord。AMS检查Service所在的进程是否存在,如果不存在就就调用Process.start(android.app.ActivityThread)创建一个新的进程。

      3.实例化ActivityThread对象并执行其中的main方法,并对主线程Looper进行初始化。App进程启动后会将ActivityThread通过ActivityManagerProxy发送给AMS

      4.AMS接收到ActivityThread后会将ActivityThread包装秤ApplicationThreadProxy,然后通过ApplicationThreadProxy.scheduleBindService向App进程发送消息

      5.App进程通过ApplicationThread接收到消息后会调用ActivityThread.sendMessage方法向H发送消息,H通过handleMessage接收到消息后会调用handleBindService对Service进行实例化并调用其onCreate函数。之后会调用Service的onBind函数把Binder发送给AMS

      

      

  • 相关阅读:
    websocket协议
    vue组件之间的传值
    vue中非父子组件的传值bus的使用
    $.proxy的使用
    弹性盒模型display:flex
    箭头函数与普通函数的区别
    粘贴到Excel的图片总是有些轻微变形
    centos rhel 中文输入法的安装
    vi ,默认为 .asm .inc 采用nasm的语法高亮
    how-to-convert-ppk-key-to-openssh-key-under-linux
  • 原文地址:https://www.cnblogs.com/tony-yang-flutter/p/12467883.html
Copyright © 2011-2022 走看看