【APP开发】Android ActivityManagerService(AMS)的启动分析

摘要:Andro

Android中的AMS想必是做android开发的工程师耳熟能详的系统级别的服务,但是它又是如此地庞大(单单ActivityManagerService.java文件就2W+行代码),因此我们在学习它的时候总是不能找到实际的主线,很是混乱。这里我会连续写几篇文章从它的启动过程,主要业务逻辑,和别的模块之间的互操作逻辑等角度来向大家简单介绍一下它。这里我只能是抛砖引玉,简单介绍,不会面面俱到,因为AMS的代码量确实比较大,如果向大家一一道来,想必大家一定会厌烦而且学习效果不好。希望大家在阅读本文的时候,同时查看android相关源码,自己动手,自己思考,你会有很大的提高的!

注:本文的所有的分析全部基于google最新的android 6.0.0进行的,6.0之前的版本可能有很多地方不一致,请知悉。

好了下面,我们就开始从头分析一下AMS,首先从AMS的启动流程开始。

Android中的很多使用java语言编写的service都是在SystemServer中启动的,SystemServer是由系统启动的时候zygote启动的第一个java程序。AMS的是在SystemServer中的startBootstrapServices方法中启动的,android系统中的很多核心关键服务都是在这个函数中启动的,这个方法中有这么一段代码:

startBootstrapServices@SystemServer.java:// Activity manager runs the show. mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService;mActivityManagerService.setSystemServiceManager(mSystemServiceManager);.setInstaller(installer);

这里调用了mSystemServiceManager对象的startService启动了AMS,注意这里给出的参数是ActivityManagerService.Lifecycle.class,在进一步分析startService之前,我们需要看一下这个类:

Lifecycle@ActivityManagerService.javapublicstaticfinalclassLifecycleextendsSystemService{privatefinalActivityManagerService mService;publicLifecycle(Context context) {super(context); mService =newActivityManagerService(context); }@OverridepublicvoidonStart { mService.start; }publicActivityManagerServicegetService {returnmService; } }

从这个类的名字就可以看出来,这是一个关于AMS的生命周期的内部类,构造器中实例化了一个AMS的对象。同时这个类继承自SystemService类(这是所有系统级别服务都应该继承的父类,主要定义了一些关于生命周期和上下文的接口),并且复写了onStart方法:

onStart@SystemService.java/** * Called when the dependencies listed in the@Serviceclass-annotation are available * and after the chosen start phase. * When this method returns, the service should be published. */publicabstractvoidonStart;

可以看出来,这是当服务启动的时候回调的方法,具体再哪里调用,我们后面会分析。弄清楚了Lifecycle类之后,我们现在可以来分析mSystemServiceManager对象的startService方法,mSystemServiceManager是SystemServiceManager类的一个对象,下面是startService方法:

startService@SystemServiceManager.java/** * Creates and starts a system service. The class must be a subclass of * {@linkcom.android.server.SystemService}. * *@paramserviceClass A Java class that implements the SystemService interface. *@returnThe service instance, never null. *@throwsRuntimeException if the service fails to start. */@SuppressWarnings("unchecked") public <TextendsSystemService> T startService(Class<T> serviceClass) {finalString name = serviceClass.getName; Slog.i(TAG,"Starting "+ name);// Create the service.if(!SystemService.class.isAssignableFrom(serviceClass)) {thrownewRuntimeException("Failed to create "+ name +": service must extend "+ SystemService.class.getName); }finalT service;try{ Constructor<T> constructor = serviceClass.getConstructor(Context.class); service = constructor.newInstance(mContext); }catch(InstantiationException ex) {thrownewRuntimeException("Failed to create service "+ name +": service could not be instantiated", ex); }catch(IllegalAccessException ex) {thrownewRuntimeException(+ name +": service must have a public constructor with a Context argument", ex); }catch(NoSuchMethodException ex) {thrownewRuntimeException(+ name +, ex); }catch(InvocationTargetException ex) {thrownewRuntimeException(+ name +": service constructor threw an exception", ex); }// Register it.mServices.add(service);// Start it.try{ service.onStart; }catch(RuntimeException ex) {thrownewRuntimeException("Failed to start service "+ name +": onStart threw an exception", ex); }returnservice; }

这里我们需要说明一下,在上面调用这个方法的时候,我们传递进来的参数是一个类,而不是这个类的对象,也就是说我们仅仅给出了类型并没有进行实例化!因此这里的方法参数是一个泛型。在这个方法中我们首先获得传递进来类的名字,然后进行一个很重要的操作,那就是java类型判断,使用isAssignableFrom完成,isAssignableFrom和instanceof类似,只是instanceof针对类的对象进行判断,而isAssignableFrom针对类进行判断,也就是说这是在只有类而没有类的对象的时候进行判断类之间的继承关系的方式。更多关于isAssignableFrom和instanceof的区别请看博客:

我们这里判断了传递进来的类是不是SystemService类的子类,如果不是的话直接刨除运行时异常立即停止运行,因为服务必须继承自SystemService类!代码中的异常信息也可以看到这一点。接下来,就获得类的构造器,并且实例化一个对象:// 获得构造器Constructor<Tconstructor=serviceClass.getConstructor(Context.class);// 实例化一个对象service =constructor.newInstance(mContext);

现在我们需要看一下实例化的时候做了什么工作,下面是Lifecycle类的构造器:

publicLifecycle(Context context) {super(context); mService =newActivityManagerService(context); }

我们可以看到,这里实例化了一个ActivityManagerService类的对象,我们看一下ActivityManagerService类的构造器:

// Note: This method is invoked on the main thread but may need to attach various// handlers to other threads. So take care to be explicit about the looper.publicActivityManagerService(Context systemContext) { mContext = systemContext; mFactoryTest = FactoryTest.getMode; mSystemThread = ActivityThread.currentActivityThread; Slog.i(TAG,"Memory class: "+ ActivityManager.staticGetMemoryClass); mHandlerThread =newServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND,false/*allowIo*/); mHandlerThread.start; mHandler =newMainHandler(mHandlerThread.getLooper); mUiHandler =newUiHandler; mFgBroadcastQueue =newBroadcastQueue(this, mHandler,"foreground", BROADCAST_FG_TIMEOUT,false); mBgBroadcastQueue =newBroadcastQueue(this, mHandler,"background", BROADCAST_BG_TIMEOUT,true); mBroadcastQueues[0] = mFgBroadcastQueue; mBroadcastQueues[1] = mBgBroadcastQueue; mServices =newActiveServices(this); mProviderMap =newProviderMap(this);// TODO: Move creation ofbattery stats service outside of activity manager service.FiledataDir = Environment.getDataDirectory; File systemDir =newFile(dataDir,"system"); systemDir.mkdirs; mBatteryStatsService =newBatteryStatsService(systemDir, mHandler); mBatteryStatsService.getActiveStatistics.readLocked; mBatteryStatsService.scheduleWriteToDisk; mOnBattery = DEBUG_POWER ?true: mBatteryStatsService.getActiveStatistics.getIsOnBattery; mBatteryStatsService.getActiveStatistics.setCallback(this); mProcessStats =newProcessStatsService(thisnewFile(systemDir,"procstats")); mAppOpsService =newAppOpsService(newFile(systemDir,"appops.xml"), mHandler); mGrantFile =newAtomicFile(newFile(systemDir,"urigrants.xml"));// User 0 is the first and only user that runs at boot.mStartedUsers.put(UserHandle.USER_OWNER,newUserState(UserHandle.OWNER,true)); mUserLru.add(UserHandle.USER_OWNER); updateStartedUserArrayLocked; GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", ConfigurationInfo.GL_ES_VERSION_UNDEFINED); mTrackingAssociations ="1".equals(SystemProperties.get("debug.track-associations")); mConfiguration.setToDefaults; mConfiguration.setLocale(Locale.getDefault); mConfigurationSeq = mConfiguration.seq =1; mProcessCpuTracker.init; mCompatModePackages =newCompatModePackages(this, systemDir, mHandler); mIntentFirewall =newIntentFirewall(newIntentFirewallInterface, mHandler); mRecentTasks =newRecentTasks(this); mStackSupervisor =newActivityStackSupervisor(this, mRecentTasks); mTaskPersister =newTaskPersister(systemDir, mStackSupervisor, mRecentTasks); mProcessCpuThread =newThread("CpuTracker") { @Overridepublicvoidrun{while(true) {try{try{ synchronized(this) { finallongnow = SystemClock.uptimeMillis;longnextCpuDelay = (mLastCpuTime.get+MONITOR_CPU_MAX_TIME)-now;longnextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;//Slog.i(TAG, "Cpu delay=" + nextCpuDelay// + ", write delay=" + nextWriteDelay);if(nextWriteDelay < nextCpuDelay) { nextCpuDelay = nextWriteDelay; }if(nextCpuDelay >0) { mProcessCpuMutexFree.set(true);this.wait(nextCpuDelay); } } }catch(InterruptedException e) { } updateCpuStatsNow; }catch(Exception e) { Slog.e(TAG,"Unexpected exception collecting process stats", e); } } } }; Watchdog.getInstance.addMonitor(this); Watchdog.getInstance.addThread(mHandler); }

这个构造器比较长,并且基本都是一些AMS日常工作的初始化,因此我们这里就不详细分析构造器的工作了,后面分析AMS的服务逻辑的时候我们在来分析对应的初始化工作。现在我们只要知道在AMS的构造器中做了这些工作就可以了:

1. 创建一堆类的对象,这些对象对于AMS的日常工作来说是必需的。

2. 初始化battery stats相关服务,AMS除了负责activity的管理工作,还负责battery stats相关的工作

3. 初始化cpu统计相关服务,主要是启动一个线程,轮询处理。为AMS提供有关CPU运行统计方面数据做准备。

最后进行这个方法中最重要的操作,那就是将服务添加到ServiceManager中去,方面别的进程使用Binder查找到这个服务:// Register it.mServices.add(service);

需要注意的是,这里的添加注册服务并不是Binder添加注册服务,我们看一下mServices的类型就知道了:

// Services that should receive lifecycle events.privatefinalArrayList<SystemService> mServices =newArrayList<SystemService>;

是的,mServices就是一个列表,这个列表中包含了它启动的所有SystemService类的服务,以便于后面调用它的生命周期方法。

接下来的操作就是回调我们前面提到的onStart方法:// Start it.try{ service.onStart; }catch(RuntimeException ex) {thrownewRuntimeException("Failed to start service "+ name +": onStart threw an exception", ex); }

这里就回调到了AMS中Lifecycle内部类的onStart方法了,最后就是将实例化的service返回。接下来我们先分析一下Lifecycle的onStart:

@OverridepublicvoidonStart { mService.start; }

我们看到,这里直接调用ActivityManagerService的start方法:

start@ActivityManagerService.javaprivate void start { Process.removeAllProcessGroups;mProcessCpuThread.start;mBatteryStatsService.publish(mContext);mAppOpsService.publish(mContext);Slog.d("AppOps""AppOpsService published");LocalServices.addService(ActivityManagerInternal.class, new LocalService);}

这里有的人可能觉得奇怪,怎么这个start是一个private方法?上面使用mService.start;能访问吗?是的,可以访问的,虽然它是一个私有方法!这里可以参考本人的另一篇文章:

这里的start方法很是简单,首先是调用Process类的removeAllProcessGroups方法移除所有的进程组,清空所有记录;然后就是启动ProcessCpuThread线程,mProcessCpuThread这个对象就是在刚才的构造器中初始化的;下面是发布BatteryStatsService,调用的是publish方法:

publish@BatteryStatsService.javapublic void publish(Context context) { mContext = context;ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder);mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps);mStats.setRadioScanningTimeout(mContext.getResources.getInteger(com.android.internal.R.integer.config_radioScanningTimeout) *1000L);mStats.setPowerProfile(new PowerProfile(context));}我们看到,这里首先就是将Battery stats服务注册到SM中去,然后就是设置一些运行时参数,具体这些参数是什么含义,读者可以自己分析一下BatteryStatsService的实现,这里我们就不详细分析了。

start方法的接下来的操作就是发布AppOpsService了,AppOpsService这个服务是提供android app ops服务的,什么是android app ops服务呢?App Ops是在android 4.3中加入的一个权限管理框架,这个框架可以让你自由地赋予或者撤销某个app的权限,方便管理,下图是操作时候的界面:

关于android app ops,详见:

下面是AppOpsService的publish方法:

publish@AppOpsService.javapublicvoidpublish(Context context) { mContext = context; ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder); }

我们看到,这里就更加简单了,直接就是向SM注册服务。

好了,如果读者还没有晕掉的话,你会知道上面我们都是在分析SystemServiceManager中的startService方法。。。。。(android的代码真是繁杂,长篇大论,真是烦人!)到目前为止,我们的分析流程是这样的:

1. tartBootstrapServices@SystemServer.java

2. startService@SystemServiceManager.java

3. Lifecycle@ActivityManagerService.java

4. onStart@Lifecycle

5. start@ActivityManagerService.java

现在我们回过头来看下startBootstrapServices@SystemServer.java中AMS的启动部分:

我们发现我们刚刚分析完了mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class)这部分的逻辑!!在这方法调用完成之后会返回Lifecycle类的对象(上面讲解过,不知道你是不是记得??),然后调用这个对象的getService方法赋值给mActivityManagerService,getService方法定义如下:

getService@LifecyclepublicActivityManagerServicegetService {returnmService; }

而这里的mService就是在Lifecycle构造器中实例化的ActivityManagerService对象。

接下来在SystemServer.java中的操作就是调用AMS的setSystemServiceManager来将SystemServiceManager类的对象设置进去:

setSystemServiceManager@ActivityManagerServicepublicvoidsetSystemServiceManager(SystemServiceManager mgr) { mSystemServiceManager = mgr; }

这里就只是将对象保存下来,以后会使用到。SystemServiceManager是一个创建,启动,和管理其他有关SystemService类系统服务的管理类,我们从这个类的代码注释也能看到:

/**

* Manages creating, starting, and other lifecycle events of

* {@link com.android.server.SystemService system services}.

*

* {@hide}

*/

这里说的很清楚,并且这个类的方法也是简单明了,具体这个类在AMS中怎么使用,我们后面分析AMS的业务逻辑的时候会提到。在startBootstrapServices@SystemServer.java的最后就是调用setInstaller方法将installer设置进去。installer是用来安装app的,我们的AMS使用它只是想在AMS的启动完成的时候调用installer的markBootComplete方法告诉它现在AMS启动完成了,installer可以进行工作了。这个调用是在AMS的finishBooting方法中调用的,finishBooting是ActivityStackSupervisor中初始化完毕之后回调的,ActivityStackSupervisor是用来管理ActivityStack的,这个类是android 5.0中新引入的。这部分涉及到ActivityStack的管理,所以这里不过多涉及,后面我们分析ActivityStack实现时再来详述这部分。现在大家只要知道,AMS启动最后它的finishBooting会被ActivityStackSupervisor回调,然后这个方法中会调用installer的markBootComplete,并且还会调用SystemServiceManager的startBootPhase通知启动的阶段信息:

startBootPhase@SystemServiceManager.java/** * Starts the specified boot phase for all system services that have been started up to * this point. * *@paramphase The boot phase to start. */publicvoidstartBootPhase(finalintphase) {if(phase <= mCurrentPhase) {thrownewIllegalArgumentException("Next phase must be larger than previous"); } mCurrentPhase = phase; Slog.i(TAG,"Starting phase "+ mCurrentPhase);finalintserviceLen = mServices.size;for(inti =0; i < serviceLen; i++) {finalSystemService service = mServices.get(i);try{ service.onBootPhase(mCurrentPhase); }catch(Exception ex) {thrownewRuntimeException("Failed to boot service "+ service.getClass.getName +": onBootPhase threw an exception during phase "+ mCurrentPhase, ex); } } }

这部分代码比较简单,可以看到SystemServiceManager会从mServices列表中检出所有的service并且调用他们的onBootPhase方法通知启动的阶段信息。

到这里,AMS启动只是完成基本的准备阶段,下面还有很多的工作需要做的,大家有点耐心啊~~AMS作为android系统的重量级的服务,怎么会就那么简单呢??你说是吧?还是踏踏实实地看代码吧~~~~

接下的操作还是在startBootstrapServices方法中:

startBootstrapServices@SystemServer.java// Now that the power manager has been started, let theactivity manager// initialize power management features.mActivityManagerService.initPowerManagement;

这里的操作比较简单,注释中说道,既然power manager已经启动了,那么我们的AMS就可以初始化和battery stats相关的工作了。这里我们暂时先不详细分析initPowerManagement的过程,后面我们分析AMS的电源部分的时候会详细说明这一块的内容。接着往下看startBootstrapServices的中关于AMS的代码:

//Setup the Application instanceforthe system processandgetstarted. mActivityManagerService.setSystemProcess;

这是startBootstrapServices中关于AMS的最后一个操作了,现在大家想一想,我们的AMS是一个Binder公共服务,每一个app都能通过getSystemService找到它的,但是到目前为止我们并没有看到任何关于在Binder中注册服务的逻辑啊?现在我们看一下setSystemProcess的实现:

setSystemProcess@ActivityManagerService.javapublicvoidsetSystemProcess {try{ ServiceManager.addService(Context.ACTIVITY_SERVICE,thistrue); ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); ServiceManager.addService("meminfo"newMemBinder(this)); ServiceManager.addService("gfxinfo"newGraphicsBinder(this"dbinfo"newDbBinder(this));if(MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo"newCpuBinder(this)); } ServiceManager.addService("permission"newPermissionController(this"processinfo"newProcessInfoService(this)); ApplicationInfo info = mContext.getPackageManager.getApplicationInfo("android", STOCK_PM_FLAGS); mSystemThread.installSystemApplicationInfo(info, getClass.getClassLoader);synchronized(this) { ProcessRecord app = newProcessRecordLocked(info, info.processName,false0); app.persistent =true; app.pid = MY_PID; app.maxAdj = ProcessList.SYSTEM_ADJ; app.makeActive(mSystemThread.getApplicationThread, mProcessStats);synchronized(mPidsSelfLocked) { mPidsSelfLocked.put(app.pid, app); } updateLruProcessLocked(app,falsenull); updateOomAdjLocked; } }catch(PackageManager.NameNotFoundException e) {thrownewRuntimeException("Unable to find android system package", e); } }

就是这里了,我们看到这个方法上来的第一句就是ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);这句话就是我们想要找的,这句话的意思就是通过Binder向系统服务大管家ServiceManager(SM)注册我们的服务,这样android中的其他进程就可以通过context的getSystemService找到我们的服务了。这个方法中的接下来的代码让我们感觉AMS挺不务正业的,它还分管着meminfo,gfxinfo,dbinfo,cpuinfo,permission,processinfo等业务,还真是忙啊!这里我们先不看这些业务,因为我们知道只有Activity的管理业务才是AMS的主页,其他的都只是副业而已了。

到这里,AMS的主体业务才算是启动完毕。这里我们简单分析了一下android中的AMS的在开机过程中的启动流程,目的就是给大家关于AMS启动的一个清晰的结构,并不是要面面俱到。个人感觉,android中的任何一个模块拿出来的话代码量都是巨大的,怎么从这些代码中找到android的设计的整体架构呢?最好的办法还是,先整体再模块,先抽象再具体。也就是先要知道整体的情况是什么样的,然后再研究细节部分,不然的话很有可能会深陷android代码泥沼,不能自拔……

本文来自CSDN博客