【安卓AMS启动流程】 您所在的位置:网站首页 安卓开机启动sh 【安卓AMS启动流程】

【安卓AMS启动流程】

2023-05-19 03:58| 来源: 网络整理| 查看: 265

AMS在安卓系统里面的作用

AMS主要负责四大组件的启动、切换、调度以及应用进程的管理和调度工作。所有的APP应用都需要与AMS打交道,是系统核心服务之一。

AMS的启动流程

在SystemServer.java里面的startBootstrapServices方法里面启动。startBootstrapServices方法在SystemServer.java的run方法里面被调用。SystemServer.java在类加载的时候会调用静态方法main(),里面创建了对象并且调用了run方法。

frameworks/base/services/java/com/android/server/SystemServer.java /** 607 * The main entry point from zygote. 608 */ 609 public static void main(String[] args) { 610 new SystemServer().run(); 611 }

SystemServe.javar#run()方法里面的几个核心方法:

// Initialize the system context. createSystemContext(); ... ... // Start services. try { t.traceBegin("StartServices"); startBootstrapServices(t); startCoreServices(t); startOtherServices(t); private void startBootstrapServices(@NonNull TimingsTraceAndSlog t){ ... // 开始启动AMS t.traceBegin("StartActivityManager"); //启动ActivityTaskManagerService服务,简称ATM,Android 10+新引入功能,用来管理Activity的启动、调度等功能 ActivityTaskManagerService atm=mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); //启动服务 ActivityManagerService,简称AMS mActivityManagerService=ActivityManagerService.Lifecycle.startService( mSystemServiceManager,atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mWindowManagerGlobalLock=atm.getGlobalLock(); t.traceEnd(); ... // 设置系统进程 t.traceBegin("SetSystemProcess"); mActivityManagerService.setSystemProcess(); t.traceEnd(); } createSystemContext方法

SystemServer的run函数中,在启动AMS之前,调用了createSystemContext方法,主要用来是初始化 System Context和SystemUi Context,并设置主题。 当SystemServer 调用createSystemContext()完毕后,完成以下两个内容: 1.得到了一个ActivityThread对象,它代表当前进程 (此时为系统进程) 的主线程; 2.得到了一个Context对象,对于SystemServer而言,它包含的Application运行环境与framework-res.apk有关。

// Initialize the system context. createSystemContext(); frameworks/base/services/java/com/android/server/SystemServer.java private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); //获取system context mSystemContext = activityThread.getSystemContext(); //设置系统主题 mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); //获取systemui context final Context systemUiContext = activityThread.getSystemUiContext(); //设置systemUI 主题 systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); }

systemMain函数主要作用是创建ActivityThread对象,然后调用该对象的attach方法。

frameworks/base/core/java/android/app/ActivityThread.java public static ActivityThread systemMain() { ThreadedRenderer.initForSystemProcess(); // 获取ActivityThread对象 ActivityThread thread = new ActivityThread(); thread.attach(true, 0); return thread; }

ActivityThread是Framework层中一个非常重要的类,它代表一个应用进程的主线程,其职责就是调度及执行在该线程中运行的四大组件。

public final class ActivityThread extends ClientTransactionHandler { ... // 定义了AMS与应用通信的接口,初始化ApplicationThread的对象 @UnsupportedAppUsage final ApplicationThread mAppThread = new ApplicationThread(); // 拥有自己的looper,说明ActivityThread确实可以代表事件处理线程 @UnsupportedAppUsage final Looper mLooper = Looper.myLooper(); // Hadndle初始化,ActivityThread中大量事件处理依赖此Handler @UnsupportedAppUsage final H mH = new H(); final Executor mExecutor = new HandlerExecutor(mH); // 用于保存该进程的ActivityRecord final ArrayMap mActivities = new ArrayMap(); //用于保存进程中的Service final ArrayMap mServices = new ArrayMap(); //用于保存进程中的Application final ArrayList mAllApplications = new ArrayList(); // 构造函数 @UnsupportedAppUsage ActivityThread() { // 使用单例模式获得一个ResourcesManager实例 mResourcesManager = ResourcesManager.getInstance(); }

注意到此处的ActivityThread创建于SystemServer进程中。 由于SystemServer中也运行着一些系统APK,例如framework-res.apk、SettingsProvider.apk等,因此也可以认为SystemServer是一个特殊的应用进程。 AMS负责管理和调度进程,因此AMS需要通过Binder机制和应用进程通信。 为此,Android提供了一个IApplicationThread接口,该接口定义了AMS和应用进程之间的交互函数。

ActivityThread的attach方法将进程分为应用进程、系统进程2个部分进行处理,其中对于系统进程,最重要的工作就是创建了Instrumentation、Application和Context三个重要成员,这三个成员的职责依次为: Instrumentation: Android中的一个工具类,当该类被启用时,它将优先于应用中其它的类被初始化。 Context: Android中的一个抽象类,用于维护应用运行环境的全局信息,通过Context可以访问应用的资源和类,甚至进行系统级的操作,例如启动Activity、发送广播等。 Application: 用于保存应用的全局状态。 该部分代码位于frameworks/base/core/java/android/app/ActivityThread.java

private void attach(boolean system, long startSeq) { sCurrentActivityThread = this; mConfigurationController = new ConfigurationController(this); mSystemThread = system; if (!system) { // 处理应用进程 ... } else { // 系统进程的处理流程,该情况只在SystemServer中处理 android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); try { // 创建ActivityThread中的重要成员:Instrumentation、 Application 和 Context // 初始化Instrumentation,它是Android中的一个工具类,当该类被启用时,它将优先于应用中其它的类被初始化 mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); // 创建系统的Context ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); // 调用LoadedApk的makeApplication函数,Application类用于保存应用的全局状态 mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate Application():" + e.toString(), e); } }

在SystemServer#createSystemContext()中调用的getSystemContext()方法用于创建并返回一个System Context,在这个方法中调用了ContextImpl.createSystemContext方法,该方法会创建一个LoadedApk,然后初始化一个ContextImpl对象。 注意到createSystemContext函数中,创建的LoadApk对应packageName为”android”,也就是framwork-res.apk,由于该APK仅供SystemServer进程使用,因此创建的Context被定义为System Context,由于PMS还未启动,所以现在该LoadedApk还没有得到framwork-res.apk实际的信息,当PMS启动,完成对应的解析后,AMS将重新设置这个LoadedApk。

frameworks/base/services/java/com/android/server/SystemServer.java public ContextImpl getSystemContext() { synchronized (this) { if (mSystemContext == null) { // 调用ContextImpl的createSystemContext方法 mSystemContext = ContextImpl.createSystemContext(this); } return mSystemContext; } } // [frameworks/base/core/java/android/app/ContextImpl.java] static ContextImpl createSystemContext(ActivityThread mainThread) { //创建LoadedApk类,代表一个加载到系统中的APK,由于PMS还没有启动,所以此时的LoadedApk没有任何内容 LoadedApk packageInfo = new LoadedApk(mainThread); // 获取ContextImpl对象 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, ContextParams.EMPTY, null, null, null, null, null, 0, null, null); // 初始化资源信息 context.setResources(packageInfo.getResources()); context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetrics()); context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI; return context; } ActivityTaskManagerService(ATM) 服务启动

ActivityTaskManagerService简称ATM,是Andorid 10+引入的一个新功能,用来管理Activity的启动、调度等功能,其先于AMS启动,下面来分析ATM的启动流程。 frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

public static final class Lifecycle extends SystemService { private final ActivityTaskManagerService mService; ... public Lifecycle(Context context) { super(context); // 初始化ActivityTaskManagerService对象 mService = new ActivityTaskManagerService(context); } @Override public void onStart() { publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService); // 启动ATM服务 mService.start(); } ... } public ActivityTaskManagerService(Context context) { //拿到System Context mContext = context; mFactoryTest = FactoryTest.getMode(); //取出的是ActivityThread的静态变量sCurrentActivityThread //这意味着mSystemThread与SystemServer中的ActivityThread一致 mSystemThread = ActivityThread.currentActivityThread(); //拿到System UI Context mUiContext = mSystemThread.getSystemUiContext(); mLifecycleManager = new ClientLifecycleManager(); //拿到LocalService的对象 mInternal = new LocalService(); GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED); } private void start() { // 将 ActivityTaskManagerInternal添加到本地服务的全局注册表中 LocalServices.addService(ActivityTaskManagerInternal.class, mInternal); }

从以上代码可以看出,AMT的启动分为两个部分:

创建ActivityTaskManagerService: 这一步初始化了ActivityTaskManagerService对象,这一对象以前是属于AMS的,用于Activity的管理,现在被移动到了ATM中,同时,该对象所在的路径也被移动到frameworks/base/services/core/java/com/android/server/wm路径中,这个路径原先归WindowManagerService控制,从这也可以看出,谷歌的目的也是希望在将来把activity和window融合在一起,减少冗余代码以及AMS和WMS的协调工作。 start: start方法较为简单,将ActivityTaskManagerInternal添加到本地服务的全局注册表中

至此ATM启动完成。

ActivityManagerService(AMS) 服务启动

在Android 11中,AMS负责service,broadcast,provider的管理和调度。 AMS的启动代码位于frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java,需要注意的是,AMS启动方法所在类名也为Lifecycle,这与ATM启动方法所在的类名相同,不同点在于:

ATM位于frameworks/base/services/core/java/com/android/server/wm,而AMS位于rameworks/base/services/core/java/com/android/server/am

public static final class Lifecycle extends SystemService { private final ActivityManagerService mService; private static ActivityTaskManagerService sAtm; public Lifecycle(Context context) { super(context); // 初始化ActivityManagerService,传入ATM的对象 mService = new ActivityManagerService(context, sAtm); } @Override public void onStart() { // 启动AMS服务 将ActivityManagerInternal添加到本地服务的全局注册表中 mService.start(); } } 初始化AMS对象

Android 11中,Activity的管理和调度放入到ATM中执行,AMS中保留service,broadcast,provider的管理和调度。 构造函数初始化主要工作就是初始化一些变量,供之后的service,broadcast,provider的管理和调度。 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) { ... //AMS的运行上下文与SystemServer一致 mContext = systemContext; ... //取出的是ActivityThread的静态变量sCurrentActivityThread, 这意味着mSystemThread与SystemServer中的ActivityThread一致 mSystemThread = ActivityThread.currentActivityThread(); mUiContext = mSystemThread.getSystemUiContext(); mHandlerThread = new ServiceThread(TAG, THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); mHandlerThread.start(); //AMS消息处理器 mHandler = new MainHandler(mHandlerThread.getLooper()); //UiHandler对应于Android中的UiThread mUiHandler = mInjector.getUiHandler(this); ... //创建 BroadcastQueue 前台广播对象,处理超时时长是 10s mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", foreConstants, false); //创建 BroadcastQueue 后台广播对象,处理超时时长是 60s mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", backConstants, true); //创建 BroadcastQueue 分流广播对象,处理超时时长是 60s mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler, "offload", offloadConstants, true); mBroadcastQueues[0] = mFgBroadcastQueue; } mActivityManagerService.setSystemProcess()方法

在frameworks/base/services/java/com/android/server/SystemServer.java#startBootstrapServices中调用了AMS的setSystemProcess方法,setSystemProcess方法主要有五个功能:

注册一些服务:包括 activity、procstats、meminfo、gfxinfo、dbinfo、permission、processinfo获取package名为“android”的应用的 ApplicationInfo为ActivityThread 安装 system application相关信息,将framework-res.apk对应的ApplicationInfo安装到LoadedApk中的mApplicationInfo为systemserver 主进程开辟一个ProcessRecord来维护进程的相关信息AMS进程管理相关的操作。 systemReady()方法

AMS启动完毕后调用SystemServer.java#startOtherServices方法,startOtherServices方法里面调用了 ActivityManagerService.java#systemReady()方法,相关代码如下: frameworks/base/services/java/com/android/server/SystemServer.java#startOtherServices()

mActivityManagerService.systemReady(() -> { ... })

该方法分为三个阶段

主要是调用一些关键服务的初始化函数, 然后杀死那些没有FLAG_PERSISTENT却在AMS启动完成前已经存在的进程, 同时获取一些配置参数。 需要注意的是,由于只有Java进程才会向AMS注册,而一般的Native进程不会向AMS注册,因此此处杀死的进程是Java进程。执行goingCallback的处理,主要的工作就是通知一些服务可以进行systemReady、systemRunning相关的工作,并进行启动服务或应用进程的工作启动Home Activity,当启动结束,并发送ACTION_BOOT_COMPLETED广播时,AMS的启动过程告一段落

下面结合具体代码对这三个阶段进行探究。

关键服务初始化

该阶段主要是调用一些关键服务的初始化函数,然后杀死那些没有FLAG_PERSISTENT却在AMS启动完成前已经存在的进程, 同时获取一些配置参数。 需要注意的是,由于只有Java进程才会向AMS注册,而一般的Native进程不会向AMS注册,因此此处杀死的进程是Java进程。

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog){ synchronized(this){ // 第一次进入mSystemReady 为false,不走该流程 if(mSystemReady){ if(goingCallback!=null){ goingCallback.run(); } t.traceEnd(); return; } //这一部分主要是调用一些关键服务SystemReady相关的函数, //进行一些等待AMS初始完,才能进行的工作 t.traceBegin("controllersReady"); mLocalDeviceIdleController= LocalServices.getService(DeviceIdleInternal.class); mActivityTaskManager.onSystemReady(); mUserController.onSystemReady(); mAppOpsService.systemReady(); mProcessList.onSystemReady(); mSystemReady=true; t.traceEnd(); } ... synchronized(mPidsSelfLocked){ // mPidsSelfLocked 中保存当前正在运行的所有进程的信息 for(int i=mPidsSelfLocked.size()-1;i>=0;i--){ ProcessRecord proc=mPidsSelfLocked.valueAt(i); if(!isAllowedWhileBooting(proc.info)){ if(procsToKill==null){ procsToKill=new ArrayList(); } procsToKill.add(proc); } } } ... } 执行goingCallback处理

该阶段主要的工作就是通知一些服务可以进行systemReady相关的工作,并进行启动服务或应用进程的工作。 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { ... // 调用参数传入的runnable对象,SystemServer中有具体的定义 if (goingCallback != null) goingCallback.run(); ... // 启动系统服务(在这里主要是电池状态管理服务) t.traceBegin("ActivityManagerStartApps"); mBatteryStatsService.onSystemReady(); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, Integer.toString(currentUserId), currentUserId); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, Integer.toString(currentUserId), currentUserId); final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM; if (bootingSystemUser) { mSystemServiceManager.onUserStarting(t, currentUserId); } synchronized (this) { //启动persistent为1的application所在的进程 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE); // Start up initial activity. mBooting = true; ... } }

goingCallback.run()该方法主体在frameworks/base/services/java/com/android/server/SystemServer.java#startOtherServices下,之前看到systemReady()下有一个Lambda 表达式,这个表达式的主体既为goingCallback.run()的内容,主要用于监控Native的crash,启动WebView,执行一些服务的systemReady 和systemRunning方法。

private void startOtherServices(){ mActivityManagerService.systemReady(()->{ // 阶段 550 Acitvity Manager启动完成 mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); ... // 监控Native的crash mActivityManagerService.startObservingNativeCrashes(); ... },BOOT_TIMINGS_TRACE_LOG); ... //启动WebView mWebViewUpdateService.prepareWebViewInSystemServer(); // 执行一系列服务的systemReady方法 networkManagementF.systemReady(); ipSecServiceF.systemReady(); networkStatsF.systemReady(); connectivityF.systemReady(); networkPolicyF.systemReady(networkPolicyInitReadySignal); ... //阶段 600 第三方应用程序可以启动 mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); //执行一系列服务的systemRunning方法 locationF.systemRunning(); countryDetectorF.systemRunning(); networkTimeUpdaterF.systemRunning(); inputManagerF.systemRunning(); telephonyRegistryF.systemRunning(); mediaRouterF.systemRunning(); ... }

startPersistentApps()该方法用于启动persistent为1的application所在的进程。 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

void startPersistentApps(int matchFlags) { if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return; synchronized (this) { try { final List apps = AppGlobals.getPackageManager().getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList(); for (ApplicationInfo app : apps) { //由于framework-res.apk已经由系统启动,所以此处不再启动它 if (!"android".equals(app.packageName)) { //addAppLocked中将启动application所在进程 addAppLocked(app, null, false, null /* ABI override */); } } } catch (RemoteException ex) { } } } 完成AMS启动(启动Home Activity)

在该阶段启动Home Activity,当启动结束,并发送ACTION_BOOT_COMPLETED广播时,AMS启动完成。 frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

//ActivityManagerService.java#finishBooting()方法里面 .... // Tell anyone interested that we are done booting! SystemProperties.set("sys.boot_completed", "1"); @Override public void bootAnimationComplete() { final boolean callFinishBooting; synchronized (this) { callFinishBooting = mCallFinishBooting; mBootAnimationComplete = true; } if (callFinishBooting) { finishBooting(); } }

开机动画执行完毕后会调用finishBooting方法。

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { ... // 通过ATM,启动Home Activity mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); ... // 发送广播消息 try { // system发送广播 ACTION_USER_STARTED = "android.intent.action.USER_STARTED"; Intent intent = new Intent(Intent.ACTION_USER_STARTED); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY| Intent.FLAG_RECEIVER_FOREGROUND); intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, intent,null, null, 0, null, null, null, OP_NONE,null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,currentUserId); //system发送广播 ACTION_USER_STARTING= "android.intent.action.USER_STARTING"; intent = new Intent(Intent.ACTION_USER_STARTING); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId); broadcastIntentLocked(null, null, intent,null, new IIntentReceiver.Stub() { @Override public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException { } }, 0, null, null, new String[] {INTERACT_ACROSS_USERS}, OP_NONE, null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,UserHandle.USER_ALL); } catch (Throwable t) { } finally { } }

安卓的Luncher其实就是在这里启动的,启动完成后,我们就可以看见安卓系统的主界面了。 frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

public boolean startHomeOnAllDisplays(int userId, String reason) { synchronized (mGlobalLock) { //调用RootActivityContainer的startHomeOnAllDisplays(),最终到startHomeOnDisplay() return mRootWindowContainer.startHomeOnAllDisplays(userId, reason); } } // [frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java] boolean startHomeOnAllDisplays(int userId, String reason) { boolean homeStarted = false; for (int i = getChildCount() - 1; i >= 0; i--) { final int displayId = getChildAt(i).mDisplayId; homeStarted |= startHomeOnDisplay(userId, reason, displayId);} return homeStarted; } // [frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java] boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,boolean fromHomeKey) { // Fallback to top focused display or default display if the displayId is invalid. if (displayId == INVALID_DISPLAY) { final Task rootTask = getTopDisplayFocusedRootTask(); displayId = rootTask != null ? rootTask.getDisplayId() : DEFAULT_DISPLAY; } final DisplayContent display = getDisplayContent(displayId); return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) -> result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea, allowInstrumenting, fromHomeKey), false /* initValue */); } // [frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java] boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea, boolean allowInstrumenting, boolean fromHomeKey) { ... // 启动Home Activity--Luncher mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason, taskDisplayArea); return true; } 总结

Android 9.0 及以前版本,Acitivity 管理由AMS 和WMS 协作完成,导致在AMS 和WMS 中都有相似功能的实体,除了大量的代码冗余之外,二者之间的协作也非常困难,从Android 11 的代码变更看,google 最终的目的是把activity 和window融合,其实activity和window的融合早在Android 10就开始了,但目前只是简单的把代码整理到一起了。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有