AMS启动流程

news2024/9/20 18:37:46

本文均采用Android 14代码进行讲解,学习可以使用以下地址:Search

一、AMS启动流程

AMS的启动是在SyetemServer进程中启动的,从SyetemServer的main方法开始进入:

1.SystemServer.java

main(String[] args)

/**
 * The main entry point from zygote.
 */
public static void main(String[] args) {
    new SystemServer().run();
}

main方法中只调用了SystemServer的run方法,如下所示。

run()

从下面的注释中可以看到,官方把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务是一些非紧要和一些不需要立即启动的服务。系统服务总共大约有80多个,我们主要来查看引导服务AMS是如何启动的。

private void run() {
      		 // Initialize native services.
         	//1.加载了动态库libandroid_servers.so
           System.loadLibrary("android_servers");
       ......
	         // Create the system service manager.
        	 //2.创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。
	         mSystemServiceManager = new SystemServiceManager(mSystemContext);
	         mSystemServiceManager.setStartInfo(mRuntimeRestart,
	                 mRuntimeStartElapsedTime, mRuntimeStartUptime);
	         mDumper.addDumpable(mSystemServiceManager);
	     ......   
			    	// Start services.
        try {
           t.traceBegin("StartServices");
           //用SystemServiceManager启动了ActivityManagerService、PowerManagerService、PackageManagerService等服务。
			 		 startBootstrapServices(t);
           //启动了BatteryService、UsageStatsService和WebViewUpdateService。
           startCoreServices(t);
        	 //启动了CameraService、AlarmManagerService、VrManagerService等服务。这些服务的父类均为SystemService。
           startOtherServices(t);
        	 startApexServices(t);
           // Only update the timeout after starting all the services so that we use
           // the default timeout to start system server.
           updateWatchdogTimeout(t);
       } catch (Throwable ex) {
           Slog.e("System", "******************************************");
           Slog.e("System", "************ Failure starting system services", ex);
           throw ex;
       } finally {
           t.traceEnd(); // StartServices
       }
       ...
   }

startBootstrapServices(@NonNull TimingsTraceAndSlog t)

调用了ActivityManagerService.Lifecycle.startService方法

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
    t.traceBegin("startBootstrapServices");
  	//尽早启动watchdog,这样我们就可以使系统服务器崩溃
    // 如果我们在早期启动时死锁
    t.traceBegin("StartWatchdog");
    final Watchdog watchdog = Watchdog.getInstance();
    watchdog.start();
    mDumper.addDumpable(watchdog);	
    .....
    // Activity manager runs the show.
    t.traceBegin("StartActivityManager");
    // TODO: Might need to move after migration to WM.
    ActivityTaskManagerService atm = mSystemServiceManager.startService(
            ActivityTaskManagerService.Lifecycle.class).getService();
    //调用了ActivityManagerService.Lifecycle.startService方法,跟进代码看最终调用哪个方法
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(
            mSystemServiceManager, atm);
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
    mActivityManagerService.setInstaller(installer);
    mWindowManagerGlobalLock = atm.getGlobalLock();
    t.traceEnd();
......

2.ActivityManagerService.java

Lifecycle.startService(SystemServiceManager ssm,ActivityTaskManagerService atm)

最终调用SystemServiceManager的startService方法,参数就是ActivityManagerService.Lifecycle.class,继续跟进SystemServiceManager,最终调用Lifecycle的getService方法,这个方法会返回AMS类型的mService对象,这样AMS实例就会被创建并且返回。

//Lifecycle继承自SystemService
public static final class Lifecycle extends SystemService {
	  public Lifecycle(Context context) {
	      super(context);
      	//当通过反射来创建Lifecycle实例时,会调用此方法创建AMS实例
	      mService = new ActivityManagerService(context, sAtm);
	  }
    public static ActivityManagerService startService(
            SystemServiceManager ssm, ActivityTaskManagerService atm) {
        sAtm = atm;
      	//调用SystemServiceManager的startService方法,参数就是ActivityManagerService.Lifecycle.class,最终调用Lifecycle的getService方法,这个方法会返回AMS类型的mService对象,这样AMS实例就会被创建并且返回。
        return ssm.startService(ActivityManagerService.Lifecycle.class).getService();
				@Override
		public void onStart(){
				Service.start;
		}
  	...
  	//这个方法会返回AMS类型的mService对象,这样AMS实例就会被创建并且返回。
     public ActivityManagerService getService() {
         return mService;
     }
}

3.SystemServiceManager.java

startService(Class<T> serviceClass)

首先会获取传进来的Lifecycle的构造器constructor,然后调用constructor的newInstance方法来创建Lifecycle类型的service对象,调用重载的startService,最后返回service

public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
        final String name = serviceClass.getName();
        Slog.i(TAG, "Starting " + name);
        Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

        // Create the service.
        if (!SystemService.class.isAssignableFrom(serviceClass)) {
            throw new RuntimeException("Failed to create " + name
                    + ": service must extend " + SystemService.class.getName());
        }
        final T service;
        try {
        	  //1.获取传进来的Lifecycle的构造器constructor
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            //调用constructor的newInstance方法来创建Lifecycle类型的service对象
						service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service could not be instantiated", ex);
        } catch (IllegalAccessException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service must have a public constructor with a Context argument", ex);
        } catch (NoSuchMethodException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service must have a public constructor with a Context argument", ex);
        } catch (InvocationTargetException ex) {
            throw new RuntimeException("Failed to create service " + name
                    + ": service constructor threw an exception", ex);
        }
      	//调用重载的startService
        startService(service);
      	//返回service
        return service;
    } finally {
        Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
    }
}

startService(@NonNull final SystemService service)

首先会将上面创建的service添加到ArrayList类型的mServices对象中来完成注册,然后调用service的onStart方法来启动service

public void startService(@NonNull final SystemService service) {
    // Check if already started
    String className = service.getClass().getName();
    if (mServiceClassnames.contains(className)) {
        Slog.i(TAG, "Not starting an already started service " + className);
        return;
    }
    mServiceClassnames.add(className);

    //1.将上面创建的service添加到ArrayList类型的mServices对象中来完成注册
    mServices.add(service);

    // Start it.
    long time = SystemClock.elapsedRealtime();
    try {
      	//2.调用service的onStart方法来启动service
        service.onStart();
    } catch (RuntimeException ex) {
        throw new RuntimeException("Failed to start service " + service.getClass().getName()
                + ": onStart threw an exception", ex);
    }
    warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
}

4.流程总结:

总的流程主要涉及SystemServer、ActivityManagerService、SystemServiceManager三个类,SystemServer的run方法会调用去启动引导服务startBootstrapServices,其中AMS也在里面,startBootstrapServices调用了startService方法,跟进代码看最终调用SystemServiceManager里面的startService,中间会有一系列的调用,但最后会通过Lifecycle创建AMS实例,然后通过Lifecycle里面的getService(),这个方法会返回AMS类型的mService对象。

二、

三、Activity的启动流程

Activity的启动流程,Android 7使用了代理模式的方式通讯,Android8.0开始使用了aidl的方式进行通信,这里以Android13和Android的代码流程为例。

Android13

Android 7

ActivityManager是一个和AMS相关联的类,它主要对运行中的Activity进行管理,这些管理工作并不是由ActivityManager来处理的,而是交由AMS来处理,ActivityManager中的方法会通过ActivityManagerNative(以后简称AMN)的getDefault方法来得到ActivityManagerProxy(以后简称AMP),通过AMP就可以和AMN进行通信,而AMN是一个抽象类,它会将功能交由它的子类AMS来处理,因此,AMP就是AMS的代理类。AMS作为系统核心服务,很多API是不会暴露给ActivityManager的,因此 并不算是AMS家族一份子。

为了讲解AMS家族,这里拿Activity的启动过程举例,Activity的启动过程中会调用Instrumentation的execStartActivity方法,如下所示。

frameworks/base/core/java/android/app/Instrumentation.java

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
      ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

execStartActivity方法中会调用AMN的getDefault来获取AMS的代理类AMP。接着调用了AMP的startActivity方法,先来查看AMN的getDefault方法做了什么,如下所示。

frameworks/base/core/java/android/app/ActivityManagerNative.java

 static public IActivityManager getDefault() {
        return gDefault.get();
    }
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");//1
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);//2
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }+
    };
}

getDefault方法调用了gDefault的get方法,我们接着往下看,gDefault 是一个Singleton类。注释1处得到名为”activity”的Service引用,也就是IBinder类型的AMS的引用。接着在注释2处将它封装成AMP类型对象,并将它保存到gDefault中,此后调用AMN的getDefault方法就会直接获得AMS的代理对象AMP。注释2处的asInterface方法如下所示。

frameworks/base/core/java/android/app/ActivityManagerNative.java

static public IActivityManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }
    IActivityManager in =
        (IActivityManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }
    return new ActivityManagerProxy(obj);
}

asInterface方法的主要作用就是将IBinder类型的AMS引用封装成AMP,AMP的构造方法如下所示。

frameworks/base/core/java/android/app/ActivityManagerNative.java

class ActivityManagerProxy implements IActivityManager
{
    public ActivityManagerProxy(IBinder remote)
    {
        mRemote = remote;
    }
...
 }

AMP的构造方法中将AMS的引用赋值给变量mRemote ,这样在AMP中就可以使用AMS了。

其中IActivityManager是一个接口,AMN和AMP都实现了这个接口,用于实现代理模式和Binder通信。

再回到Instrumentation的execStartActivity方法,来查看AMP的startActivity方法,AMP是AMN的内部类,代码如下所示。

frameworks/base/core/java/android/app/ActivityManagerNative.java

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
           String resolvedType, IBinder resultTo, String resultWho, int requestCode,
           int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
     ...
       data.writeInt(requestCode);
       data.writeInt(startFlags);
     ...
       mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);//1
       reply.readException();+
       int result = reply.readInt();
       reply.recycle();
       data.recycle();
       return result;
   }

首先会将传入的参数写入到Parcel类型的data中。在注释1处,通过IBinder类型对象mRemote(AMS的引用)向服务端的AMS发送一个START_ACTIVITY_TRANSACTION类型的进程间通信请求。那么服务端AMS就会从Binder线程池中读取我们客户端发来的数据,最终会调用AMN的onTransact方法,如下所示。

frameworks/base/core/java/android/app/ActivityManagerNative.java

   @Override
   public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
           throws RemoteException {
       switch (code) {
       case START_ACTIVITY_TRANSACTION:
       {
       ...
           int result = startActivity(app, callingPackage, intent, resolvedType,
                   resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
           reply.writeNoException();
           reply.writeInt(result);
           return true;
       }
   }

onTransact中会调用AMS的startActivity方法,如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 @Override
 public final int startActivity(IApplicationThread caller, String callingPackage,
         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
         int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
     return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
             resultWho, requestCode, startFlags, profilerInfo, bOptions,
             UserHandle.getCallingUserId());
 }

startActivity方法会最后return startActivityAsUser方法,如下所示。
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

 @Override
 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
         Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
         int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
     enforceNotIsolatedCaller("startActivity");
     userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
             userId, false, ALLOW_FULL_ONLY, "startActivity", null);
     return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
             resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
             profilerInfo, null, null, bOptions, false, userId, null, null);
  }           

startActivityAsUser方法最后会return ActivityStarter的startActivityMayWait方法,这一调用过程已经脱离了本节要讲的AMS家族。

在Activity的启动过程中提到了AMP、AMN和AMS,它们共同组成了AMS家族的主要部分,如下图所示。

AMP是AMN的内部类,它们都实现了IActivityManager接口,这样它们就可以实现代理模式,具体来讲是远程代理:AMP和AMN是运行在两个进程的,AMP是Client端,AMN则是Server端,而Server端中具体的功能都是由AMN的子类AMS来实现的,因此,AMP就是AMS在Client端的代理类。AMN又实现了Binder类,这样AMP可以和AMS就可以通过Binder来进行进程间通信。

Android解析ActivityManagerService(一)AMS启动流程和AMS家族_android 解析 activitymanagersservice 刘望舒-CSDN博客

android api 26 ActivityManagerNative类被弃用。代理类ActivityManagerProxy已经被删除。改用AIDL方式。_notewakeupalarm-CSDN博客

framework | Activity启动流程(android-31) - 掘金

面试必备:Android(9.0)Activity启动流程(一) - 知乎

http://androidxref.com/7.1.2_r36/

Search

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1132799.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt篇——子控件QLayoutItem与实际控件的强转

方法&#xff1a;使用qobject_cast<QLabel*>() &#xff0c;将通过itemAt(i)获取到的子控件(QLayoutItem)强转为子控件的实际类型(如QLineEdit、QLabel等)。 场景举例&#xff1a; QLabel *label qobject_cast<QLabel*>(ui->horizontalLayout_40->itemAt(0…

c#使用ExifLib库提取图像的相机型号、光圈、快门、iso、曝光时间、焦距信息等EXIF信息

近期公司组织了书画摄影比赛&#xff0c;本人作为摄影爱好者&#xff0c;平时也会拍些照片&#xff0c;这次比赛当然不能错过。为了提高获奖概率&#xff0c;选了19张图像作为参赛作品。但是&#xff0c;摄影作品要提交图像的光圈、曝光时间等参数。一两张还可以通过电脑自带软…

1024程序员节获奖名单公示~恭喜各位上榜同学

1024程序员节完美收官&#xff01; 恭喜各个分会场中奖的小伙伴~我们已于昨日的线下会场完成奖品及证书发放&#xff01; 更多优秀作品欢迎大家点击查看&#xff1a;卡奥斯开源社区 — 打造工业互联网顶级开源社区 颁奖典礼精彩回放&#xff1a;卡奥斯开源社区 — 打造工业互…

【ARM Coresight 系列文章 3.3 - ARM Coresight SWD 协议详细介绍】

文章目录 1.1 SWD 协议框图1.2 读/写时序及命令1.2.1 SWD 时序1.2.2 SWD 命令详情1.3 芯片探测1.3.1 获取芯片 ID1.4 读/写操作1.1 SWD 协议框图 SWD协议可以配置SoC内部几乎所有的寄存器。时钟信号由SWCLK 管脚输入,数据信号从SWDIO管脚输入输出。首先 HOST 对SW-DP 进行操作…

基于html5+javascript技术开发的房贷利率计算器

房贷计算器是一款专为购房者设计的实用工具应用&#xff0c;其主要功能是帮助用户详细计算房贷的还款金额、利息以及还款计划等。通过这款软件&#xff0c;用户可以更加便捷地了解到自己的还款情况和计划&#xff0c;从而更好地规划自己的财务。下面将对房贷计算器进行详细的介…

基于PHP的图像分享社交平台

有需要请加文章底部Q哦 可远程调试 基于PHP的图像分享社交平台 一 介绍 此图像分享社交平台基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。平台角色分为用户和管理员。用户可注册登录&#xff0c;发布图像&#xff0c;修改个人信息&#xff0c;评论图像…

家电翻页电子画册制作秘籍,轻松打造炫酷电子书!

在家电市场上&#xff0c;翻页电子画册已经成为了越来越多人的选择。它不仅具有传统纸质画册的优点&#xff0c;还具有更多的功能和特点&#xff0c;如翻页动画、音效等&#xff0c;让阅读变得更加有趣和生动。那么&#xff0c;如何制作一款炫酷的电子画册呢&#xff1f;今天就…

国产 87235系列USB平均功率探头

频率范围覆盖 功率测量准确度&#xff1a;0.2dB 10MHz&#xff5e;50GHz 87235系列 USB平均功率探头是一款基于USB 2.0接口的二极管检波式高精度、大动态范围平均功率测量仪器&#xff0c;可实现各种格式信号平均功率的准确测量。87235系列平均功率探头频率范围覆盖10MHz&am…

Spring Boot整合OAuth2实现GitHub第三方登录

Spring Boot整合OAuth2&#xff0c;实现GitHub第三方登录 1、第三方登录原理 第三方登录的原理是借助OAuth授权来实现&#xff0c;首先用户先向客户端提供第三方网站的数据证明自己的身份获取授权码&#xff0c;然后客户端拿着授权码与授权服务器建立连接获得一个Access Token…

【Note】链式存储结构

设计不同的结点结构&#xff0c;可以构成不同的链式存储结构。常用的有&#xff1a;二叉链表、三叉链表、线索链表&#xff08;用空链域存放指向前驱或后继的线索&#xff09;。 二叉链表存储 VS 一般二叉树 二叉链表 VS 二叉树 知识点&#xff1a; 一个二叉链表由根指针root…

2022年06月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 在Python编辑器中写好程序代码后&#xff0c;在Run菜单中&#xff0c;下列哪个命令可以用来执行程序&#xff1f;&…

消费大变革时代,三只松鼠的“高端性价比”如何突围制胜?

在浙江1天连开37家社区零食店&#xff0c;三只松鼠正在苏醒。 “三只松鼠去年是重创&#xff0c;可以讲是壮士断腕。”三只松鼠&#xff08;300783.SZ&#xff09;创始人、CEO章燎原在9月底接受红星资本局专访时总结。 过去几年&#xff0c;章燎原几乎没有接受过媒体采访。而…

计算机基础知识39

外键 外键字段>>>:部门编号 其实就是用来标识表与表之间的数据关系 # 简单的理解为该字段可以让你去到其他表中查找数据 表与表之间的关系 # 一对多、多对多、一对一、没有关系 ### 一对多的表关系&#xff1a; 员工表&#xff1a;一个员工一个部门 x …

如何使用 Pinia ORM 管理 Vue 中的状态

状态管理是构建任何Web应用程序的重要组成部分。虽然Vue提供了管理简单状态的技术&#xff0c;但随着应用程序复杂性的增加&#xff0c;处理状态可能变得更具挑战性。这就是为什么像Pinia这样的库被创建出来&#xff0c;以增强Vue的基本状态管理能力。然而&#xff0c;在大型应…

uni-app中tab选项卡的实现效果 @click=“clickTab(‘sell‘)“事件可传参数

一、效果图 二、代码 <template><view><view class"choose-tab"><view class"choose-tab-item" :class"chooseTab 0 ? active : " data-choose"0" click"clickTab">选项1</view><view …

第三天:配置+运行代码+改个保存键

1.上午 11点前 1.拉取文件 刷新依赖库看代码改需求 2.上午11点后 解决问题如下2.1 2.2 看文档看代码 3.下午2点到6点 对接前端 看演示视频看代码把软件运行起来 4.一直报错 &#xff08;依赖环境装备配比&#xff09; 5.依赖文件一直报错&#xff08;一会好 一会错&…

项目团队管理的常见难点,如何有效解决?

在项目管理中&#xff0c;项目经理经常会遇到团队成员工作不积极、工作任务互相推诿、踢皮球以及习惯性甩锅等一系列的团队管理相关的问题&#xff1b;遭遇这几大常见问题后&#xff0c;项目推进就容易陷入僵局。在这种情况下&#xff0c;如何有效解决问题&#xff0c;提升工作…

Pytorch整体工作流程代码详解(新手入门)

一、前言 本文详细介绍Pytorch的基本工作流程及代码&#xff0c;以及如何在GPU上训练模型&#xff08;如下图所示&#xff09;包括数据准备、模型搭建、模型训练、评估及模型的保存和载入。 适用读者&#xff1a;有一定的Python和机器学习基础的深度学习/Pytorch初学者。 本文…

HDR和泛光

HDR 显示器被限制为只能显示值为0.0到1.0间的颜色&#xff0c;但是在光照方程中却没有这个限制。通过使片段的颜色超过1.0&#xff0c;我们有了一个更大的颜色范围&#xff0c;这也被称作HDR(High Dynamic Range, 高动态范围) 允许用更大范围的颜色值渲染从而获取大范围的黑暗…

APP盾的防御机制及应用场景

移动应用&#xff08;APP&#xff09;在我们日常生活中扮演着越来越重要的角色&#xff0c;但随之而来的是各种网络安全威胁的增加。为了保障APP的安全性&#xff0c;APP盾作为一种专门设计用于防御移动应用威胁的工具得以广泛应用。本文将深入探讨APP盾的防御机制以及在不同应…