Android 7.0 ActivityManagerService(1) AMS的启动过程_第1页
Android 7.0 ActivityManagerService(1) AMS的启动过程_第2页
Android 7.0 ActivityManagerService(1) AMS的启动过程_第3页
Android 7.0 ActivityManagerService(1) AMS的启动过程_第4页
Android 7.0 ActivityManagerService(1) AMS的启动过程_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Android 7.0 ActivityManagerService(1) AMS的启动过程一、概况 ActivityManagerService(AMS)是Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作。AMS通信结构如下图所示:从图中可以看出: 1、AMS继承自ActivityManagerNative(AMN),并实现了Watchdog.Monitor和BatteryStatsImpl.BatteryCallback接口。2、AMN继承Java的Binder类,同时实现了IActivityManager接口,即AMN将作为Binder通

2、信的服务端为用户提供支持。3、在ActivityManagerNative类中定义了内部类ActivityManagerProxy,该类同样实现了IActivityManager接口,将作为客户端使用的服务端代理。4、其它进程将使用ActivityManager来使用AMS的服务。ActivityManager通过AMN提供的getDefault接口得到ActivityManagerProxy,然后再以Binder通信的方式调用AMS的接口。对AMS的基本情况有一个大概的了解后,我们一起来分析一下AMS的启动过程。 由于AMS启动涉及的内容比较多,我们将分段进行分析。二、createSyste

3、mContext 在进入到AMS相关的流程前,我们需要先了解一下相关的准备工作。我们已经知道了,zygote创建出的第一个java进程是SystemServer。 在SystemServer的run函数中,在启动AMS之前,调用了createSystemContext函数。其代码如下所示:./SystemServer在启动任何服务之前,就调用了createSystemContext/创建出的Context保存在mSystemContext中/ Initialize the system context.createSystemContext();/ Create the system serv

4、ice manager./SystemServiceManager负责启动所有的系统服务,使用的Context就是mSystemContextmSystemServiceManager = new SystemServiceManager(mSystemContext);.我们跟进一下createSystemContext:private void createSystemContext() /调用ActivityThread的systemMain函数,其中会创建出系统对应的Context对象 ActivityThread activityThread = ActivityThread.sys

5、temMain(); /取出上面函数创建的Context对象,保存在mSystemContext中 mSystemContext = activityThread.getSystemContext(); /设置系统主题 mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);以上函数中,最重要的就是ActivityThread.systemMain了,我们分析一下该函数。1、ActivityThread.systemMainpublic static ActivityThread systemMain() / The system process on lo

6、w-memory devices do not get to use hardware / accelerated drawing, since this can add too much overhead to the / process. if (!ActivityManager.isHighEndGfx() /虽然写着ActivityManager,但和AMS没有任何关系 /就是利用系统属性和配置信息进行判断 /关闭硬件渲染功能 ThreadedRenderer.disable(true); else ThreadedRenderer.enableForegroundTrimming()

7、; /创建ActivityThread ActivityThread thread = new ActivityThread(); /调用attach函数,参数为true thread.attach(true); return thread;从上面的代码可以看出,ActivityThread的systemMain函数中,除了进行是否开启硬件渲染的判断外,主要作用是: 创建出ActivityThread对象,然后调用该对象的attach函数。ActivityThread的构造函数比较简单:ActivityThread() mResourcesManager = ResourcesManager.

8、getInstance();比较关键的是它的成员变量:./定义了AMS与应用通信的接口final ApplicationThread mAppThread = new ApplicationThread();/拥有自己的looper,说明ActivityThread确实可以代表事件处理线程final Looper mLooper = Looper.myLooper();/H继承Handler,ActivityThread中大量事件处理依赖此Handlerfinal H mH = new H();/用于保存该进程的ActivityRecordfinal ArrayMap mActivities

9、= new ArrayMap()./用于保存进程中的Servicefinal ArrayMap mServices = new ArrayMap();./用于保存进程中的Applicationfinal ArrayList mAllApplications = new ArrayList();.我们需要知道的是,ActivityThread是Android Framework中一个非常重要的类,它代表一个应用进程的主线程,其职责就是调度及执行在该线程中运行的四大组件。 在Android中,应用进程指那些运行APK的进程,它们由zygote fork出来,其中运行着独立的dalvik虚拟机。 与

10、应用进程相对的就是系统进程,例如zygote和SystemServer。注意到此处的ActivityThread创建于SystemServer进程中。 由于SystemServer中也运行着一些系统APK,例如framework-res.apk、SettingsProvider.apk等,因此也可以认为SystemServer是一个特殊的应用进程。对于上面提到的ActivityThread的成员变量,其用途基本上可以从名称中得知,这里仅说明一下ApplicationThread。AMS负责管理和调度进程,因此AMS需要通过Binder机制和应用进程通信。 为此,Android提供了一个IApp

11、licationThread接口,该接口定义了AMS和应用进程之间的交互函数。如上图所示,ActivityThread作为应用进程的主线程代表,在其中持有ApplicationThread。ApplicationThread继承ApplicationThreadNative。 当AMS与应用进程通信时,ApplicationThread将作为Binder通信的服务端。AMS与应用进程通信时,通过ApplicationThreadNative获取应用进程对应的ApplicationThreadProxy对象。 通过ApplicationThreadProxy对象,将调用信息通过Binder传递到

12、ActivityThread中的ApplicationThread。 这个调用过程,今后还会遇到,碰到的时候再详细分析。2、ActivityThread.attach 我们看看ActivityThread的attach函数:/此时,我们传入的参数为true,表示该ActivityThread是系统进程的ActivityThreadprivate void attach(boolean system) /创建出的ActivityThread保存在类的静态变量sCurrentActivityThread /AMS中的大量操作将会依赖于这个ActivityThread sCurrentActivit

13、yThread = this; mSystemThread = system; if (!system) /应用进程的处理流程 . else /系统进程的处理流程,该情况只在SystemServer中处理 / Dont set application object here - if the system crashes, / we cant display an alert, we just want to die die die. /设置DDMS(Dalvik Debug Monitor Service)中看到的SystemServer进程的名称为“system_process” andr

14、oid.ddm.DdmHandleAppName.setAppName(system_process, UserHandle.myUserId(); try /创建ActivityThread中的重要成员:Instrumentation、Application和Context mInstrumentation = new Instrumentation(); ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); mInitialApplication = conte

15、xt.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); catch (Exception e) throw new RuntimeException( Unable to instantiate Application(): + e.toString(), e); /以下系统进程和非系统进程均会执行 . /注册Configuration变化的回调通知 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() Override public v

16、oid onConfigurationChanged(Configuration newConfig) /当系统配置发生变化时(例如系统语言发生变化),回调该接口 . . );从上面的代码可以看出,对于系统进程而言,ActivityThread的attach函数最重要的工作就是创建了Instrumentation、Application和Context。2.1 Instrumentation Instrumentation是Android中的一个工具类,当该类被启用时,它将优先于应用中其它的类被初始化。 此时,系统先创建它,再通过它创建其它组件。此外,系统和应用组件之间的交互也将通过Instr

17、umentation来传递。 因此,Instrumentation就能监控系统和组件的交互情况了。实际使用时,可以创建该类的派生类进行相应的操作。 这个类在介绍启动Activity的过程时还会碰到,此处不作展开。2.2 Context Context是Android中的一个抽象类,用于维护应用运行环境的全局信息。 通过Context可以访问应用的资源和类,甚至进行系统级的操作,例如启动Activity、发送广播等。ActivityThread的attach函数中,通过下面的代码创建出系统应用对应的Context:./ContextImpl是Context的实现类ContextImpl cont

18、ext = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo);.2.2.1 getSystemContext 我们先看看ActivityThread中getSystemContext的内容:public ContextImpl getSystemContext() synchronized (this) if (mSystemContext = null) /调用ContextImpl的静态函数createSystemContext mSystemContext = ContextImpl.createSy

19、stemContext(this); return mSystemContext; 进入ContextImpl的createSystemContext函数:static ContextImpl createSystemContext(ActivityThread mainThread) /创建LoadedApk类,代表一个加载到系统中的APK /注意此时的LoadedApk只是一个空壳 /PKMS还没有启动,估无法得到有效的ApplicationInfo LoadedApk packageInfo = new LoadedApk(mainThread); /调用ContextImpl的构造函数

20、 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY); /初始化资源信息 context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetrics(); return context;可以看出createSystemConte

21、xt的内容就是创建一个LoadedApk,然后初始化一个ContextImpl对象。 似乎没有什么特别的,那么为什么函数名被叫做create “System” Context?为了回答这个问题,就要看看LoadedApk的构造函数了:LoadedApk(ActivityThread activityThread) mActivityThread = activityThread; mApplicationInfo = new ApplicationInfo(); /packageName为android mApplicationInfo.packageName = android; mPack

22、ageName = android; /下面许多参数为null .注意到createSystemContext函数中,创建的LoadApk对应packageName为”android”,也就是framwork-res.apk。 由于该APK仅供SystemServer进程使用,因此创建的Context被定义为System Context。 现在该LoadedApk还没有得到framwork-res.apk实际的信息。当PKMS启动,完成对应的解析后,AMS将重新设置这个LoadedApk。2.2.2 ContextImpl.createAppContextstatic ContextImpl

23、createAppContext(ActivityThread mainThread, LoadedApk packageInfo) if (packageInfo = null) throw new IllegalArgumentException(packageInfo); return new ContextImpl(null, mainThread, packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);相对而言,createAppContext的内容就比较简单了,就是利用ActivityThread和Load

24、edApk构造出ContextImpl。 ContextImpl的构造函数主要是完成一些变量的初始化,建立起ContextImpl与ActivityThread、LoadedApk、ContentResolver之间的关系。 代码简单但是冗长,此处不做展开。2.3 Application Android中Application类用于保存应用的全局状态。我们经常使用的Activity和Service均必须和具体的Application绑定在一起。 通过上图的继承关系,每个具体的Activity和Service均被加入到Android运行环境中。在ActivityThread中,针对系统进程,通过

25、下面的代码创建了初始的Application:./调用LoadedApk的makeApplication函数mInitialApplication = context.mPackageInfo.makeApplication(true, null);/启动ApplicationmInitialApplication.onCreate();.我们看一下LoadedApk.makeApplication:public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation)

26、if (mApplication != null) return mApplication; . Application app = null; String appClass = mApplicationInfo.className; if (forceDefaultAppClass | (appClass = null) /系统进程中,对应下面的appClass appClass = android.app.Application; try java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals(andro

27、id) . ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); /实际上最后通过反射创建出Application app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); catch (Exception e) . /一个进程支持多个Application,mAllApplications用于保存该进程中的Applicat

28、ion对象 mActivityThread.mAllApplications.add(app); mApplication = app; .从上面的代码不难看出,这部分主要是创建framework-res.apk对应的Application,然后调用它的onCreate函数,完成启动。总结 至此,createSystemContext函数介绍完毕。当SystemServer调用createSystemContext完毕后: 1、得到了一个ActivityThread对象,它代表当前进程 (此时为系统进程) 的主线程; 2、得到了一个Context对象,对于SystemServer而言,它包含的

29、Application运行环境与framework-res.apk有关。在继续分析AMS之前,我们先停下来思考一下,为什么在启动所有的服务前,SystemServer先要调用createSystemContext?个人觉得深入理解Android对这个问题,解释的比较好,大致意思如下: Android努力构筑了一个自己的运行环境。 在这个环境中,进程的概念被模糊化了。组件的运行及它们之间的交互均在该环境中实现。createSystemContext函数就是为SystemServer进程搭建一个和应用进程一样的Android运行环境。Android运行环境是构建在进程之上的,应用程序一般只和And

30、roid运行环境交互。 基于同样的道理,SystemServer进程希望它内部运行的应用, 也通过Android运行环境交互,因此才调用了createSystemContext函数。创建Android运行环境时, 由于SystemServer的特殊性,调用了ActivityThread.systemMain函数; 对于普通的应用程序,将在自己的主线程中调用ActivityThread.main函数。上图表示了进程的Android运行环境涉及的主要类之间的关系。 其中的核心类是ContextImpl,通过它可以得到ContentResolver、系统资源、应用信息等。三、AMS初始化 创建完An

31、droid运行环境后,SystemServer调用startBootstrapServices,其中就创建并启动了AMS:private void startBootstrapServices() Installer installer = mSystemServiceManager.startService(Installer.class); / Activity manager runs the show. /启动AMS,然后获取AMS保存到变量中 mActivityManagerService = mSystemServiceManager.startService( ActivityM

32、anagerService.Lifecycle.class).getService(); /以下均是将变量存储到AMS中 mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); .注意到上面的代码并没有直接启动AMS,而是启动AMS的内部类Lifecycle。 这是迫不得已的做法,由于AMS并没有继承SystemService,因此不能通过SystemServiceManager的startService直接启

33、动它。 可以这样理解:内部类Lifecycle对于AMS而言,就像一个适配器一样,让AMS能够像SystemService一样被SystemServiceManager通过反射的方式启动。public static final class Lifecycle extends SystemService private final ActivityManagerService mService; public Lifecycle(Context context) /Lifecycle由SystemServiceManager启动,传入的context就是SystemServer创建出的Syste

34、mContext super(context); /1、调用AMS的构造函数 mService = new ActivityManagerService(context); Override public void onStart() /2、调用AMS的start函数 mService.start(); public ActivityManagerService getService() return mService; 接下来我们分别看看AMS的构造函数和start函数。1、AMS的构造函数 先来看看AMS的构造函数:public ActivityManagerService(Context

35、 systemContext) /AMS的运行上下文与SystemServer一致 mContext = systemContext; . /取出的是ActivityThread的静态变量sCurrentActivityThread /这意味着mSystemThread与SystemServer中的ActivityThread一致 mSystemThread = ActivityThread.currentActivityThread(); . mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_

36、FOREGROUND, false /*allowIo*/); mHandlerThread.start(); /处理AMS中消息的主力 mHandler = new MainHandler(mHandlerThread.getLooper(); /UiHandler对应于Android中的UiThread mUiHandler = new UiHandler(); if (sKillHandler = null) sKillThread = new ServiceThread(TAG + :kill, android.os.Process.THREAD_PRIORITY_BACKGROUND

37、, true /* allowIo */); sKillThread.start(); /用于接收消息,杀死进程 sKillHandler = new KillHandler(sKillThread.getLooper(); /创建两个BroadcastQueue,前台的超时时间为10s,后台的超时时间为60s mFgBroadcastQueue = new BroadcastQueue(this, mHandler, foreground, BROADCAST_FG_TIMEOUT, false); mBgBroadcastQueue = new BroadcastQueue(this, m

38、Handler, background, BROADCAST_BG_TIMEOUT, true); mBroadcastQueues0 = mFgBroadcastQueue; mBroadcastQueues1 = mBgBroadcastQueue; /创建变量,用于存储信息 mServices = new ActiveServices(this); mProviderMap = new ProviderMap(this); mAppErrors = new AppErrors(mContext, this); /这一部分,分析BatteryStatsService时提过,进行BSS的初始

39、化 File dataDir = Environment.getDataDirectory(); File systemDir = new File(dataDir, system); systemDir.mkdirs(); mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); mBatteryStatsService.getActiveStatistics().readLocked(); mBatteryStatsService.scheduleWriteToDisk(); mOnBattery = DEBU

40、G_POWER ? true : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); mBatteryStatsService.getActiveStatistics().setCallback(this); /创建ProcessStatsService,感觉用于记录进程运行时的统计信息,例如内存使用情况,写入/proc/stat文件 mProcessStats = new ProcessStatsService(this, new File(systemDir, procstats); /启动Android的权限检查服务,

41、并注册对应的回调接口 mAppOpsService = new AppOpsService(new File(systemDir, appops.xml), mHandler); mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null, new IAppOpsCallback.Stub() Override public void opChanged(int op, int uid, String packageName) if (op = AppOpsManager.OP_RUN_IN_BACKGRO

42、UND & packageName != null) if (mAppOpsService.checkOperation(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) runInBackgroundDisabled(uid); ); /用于定义ContentProvider访问指定Uri对应数据的权限,aosp中似乎没有这文件 mGrantFile = new AtomicFile(new File(systemDir, urigrants.xml); /创建多用户管理器 mUserController = new UserContr

43、oller(this); /获取OpenGL版本 GL_ES_VERSION = SystemProperties.getInt(ro.opengles.version, ConfigurationInfo.GL_ES_VERSION_UNDEFINED); . /资源配置信息置为默认值 mConfiguration.setToDefaults(); mConfiguration.setLocales(LocaleList.getDefault(); mConfigurationSeq = mConfiguration.seq = 1; /感觉用于记录进程的CPU使用情况 mProcessCp

44、uTracker.init(); /解析/data/system/packages-compat.xml文件,该文件用于存储那些需要考虑屏幕尺寸的APK的一些信息 /当APK所运行的设备不满足要求时,AMS会根据xml设置的参数以采用屏幕兼容的方式运行该APK mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); /用于根据规则过滤一些Intent mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);

45、 /以下的类,似乎用于管理和监控AMS维护的Activity Task信息 /ActivityStackSupervisor是AMS中用来管理Activity启动和调度的核心类 mStackSupervisor = new ActivityStackSupervisor(this); mActivityStarter = new ActivityStarter(this, mStackSupervisor); mRecentTasks = new RecentTasks(this, mStackSupervisor); /创建线程用于统计进程的CPU使用情况 mProcessCpuThread

46、 = new Thread(CpuTracker) Override public void run() while (true) try try /计算更新信息的等待间隔 /同时利用wait等待计算出的间隔时间 . catch(InterruptedException e) /更新CPU运行统计信息 updateCpuStatsNow(); catch (Exception e) . ; /加入Watchdog的监控 Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler);从代码来

47、看,AMS的构造函数还是相对比较简单的,主要工作就是初始化一些变量。 大多数变量的用途,从命名上基本可以推测出来,实际的使用情况必须结合具体的场景才能进一步了解。2、AMS的start函数private void start() /完成统计前的复位工作 Process.removeAllProcessGroups(); /开始监控进程的CPU使用情况 mProcessCpuThread.start(); /注册服务 mBatteryStatsService.publish(mContext); mAppOpsService.publish(mContext); Slog.d(AppOps, A

48、ppOpsService published); LocalServices.addService(ActivityManagerInternal.class, new LocalService();AMS的start函数比较简单,主要是: 1、启动CPU监控线程。该线程将会开始统计不同进程使用CPU的情况。 2、发布一些服务,如BatteryStatsService、AppOpsService(权限管理相关)和本地实现的继承ActivityManagerInternal的服务。至此AMS初始化相关的内容基本结束,从这些代码可以看出AMS涉及的类比较多,我们目前无法一一详述每个类的具体用途。 有机会遇到具体的场景时,再深入分析,此处有个大致印象即可。四、将SystemServer纳入AMS的管理体系 1、setSystemProcessAMS完成启动后,在SystemServer的startBootstrapServices函数中, 下一个与AMS相关的重要调用就是AMS.setSyste

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论