国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > 综合技术 > Android ActivityManagerService(AMS)的启动分析

Android ActivityManagerService(AMS)的启动分析

来源:程序员人生   发布时间:2016-07-01 12:56:19 阅读次数:3689次

Android中的AMS想必是做android开发的工程师耳熟能详的系统级别的服务,但是它又是如此地庞大(单单ActivityManagerService.java文件就2W+行代码),因此我们在学习它的时候总是不能找到实际的主线,很是混乱。这里我会连续写几篇文章从它的启动进程,主要业务逻辑,和别的模块之间的互操作逻辑等角度来向大家简单介绍1下它。这里我只能是抛砖引玉,简单介绍,不会四平八稳,由于AMS的代码量确切比较大,如果向大家逐一道来,想必大家1定会厌烦而且学习效果不好。希望大家在浏览本文的时候,同时查看android相干源码,自己动手,自己思考,你会有很大的提高的!
注:本文的所有的分析全部基于google最新的android 6.0.0进行的,6.0之前的版本可能有很多地方不1致,请知悉。
好了下面,我们就开始从头分析1下AMS,首先从AMS的启动流程开始。

AMS的启动进程

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

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

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

public static final class Lifecycle extends SystemService { private final ActivityManagerService mService; public Lifecycle(Context context) { super(context); mService = new ActivityManagerService(context); } @Override public void onStart() { mService.start(); } public ActivityManagerService getService() { return mService; } }

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

/** * Called when the dependencies listed in the @Service class-annotation are available * and after the chosen start phase. * When this method returns, the service should be published. */ public abstract void onStart();

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

/** * Creates and starts a system service. The class must be a subclass of * {@link com.android.server.SystemService}. * * @param serviceClass A Java class that implements the SystemService interface. * @return The service instance, never null. * @throws RuntimeException if the service fails to start. */ @SuppressWarnings("unchecked") public <T extends SystemService> T startService(Class<T> serviceClass) { final String name = serviceClass.getName(); Slog.i(TAG, "Starting " + 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 { Constructor<T> constructor = serviceClass.getConstructor(Context.class); 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); } // Register it. mServices.add(service); // Start it. try { service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + name + ": onStart threw an exception", ex); } return service; }

这里我们需要说明1下,在上面调用这个方法的时候,我们传递进来的参数是1个类,而不是这个类的对象,也就是说我们仅仅给出了类型并没有进行实例化!因此这里的方法参数是1个泛型。在这个方法中我们首先取得传递进来类的名字,然落后行1个很重要的操作,那就是java类型判断,使用isAssignableFrom完成,isAssignableFrom和instanceof类似,只是instanceof针对类的对象进行判断,而isAssignableFrom针对类进行判断,也就是说这是在只有类而没有类的对象的时候进行判断类之间的继承关系的方式。更多关于isAssignableFrom和instanceof的区分请看博客:
http://blog.csdn.net/kjfcpua/article/details/7045207
我们这里判断了传递进来的类是否是SystemService类的子类,如果不是的话直接刨除运行时异常立即停止运行,由于服务必须继承自SystemService类!代码中的异常信息也能够看到这1点。接下来,就取得类的构造器,并且实例化1个对象:

// 取得构造器 Constructor<T> constructor = serviceClass.getConstructor(Context.class); // 实例化1个对象 service = constructor.newInstance(mContext);

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

public Lifecycle(Context context) { super(context); mService = new ActivityManagerService(context); }

我们可以看到,这里实例化了1个ActivityManagerService类的对象,我们看1下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. public ActivityManagerService(Context systemContext) { mContext = systemContext; mFactoryTest = FactoryTest.getMode(); mSystemThread = ActivityThread.currentActivityThread(); Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); mHandlerThread.start(); mHandler = new MainHandler(mHandlerThread.getLooper()); mUiHandler = new UiHandler(); mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", BROADCAST_FG_TIMEOUT, false); mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", BROADCAST_BG_TIMEOUT, true); mBroadcastQueues[0] = mFgBroadcastQueue; mBroadcastQueues[1] = mBgBroadcastQueue; mServices = new ActiveServices(this); mProviderMap = new ProviderMap(this); // TODO: Move creation of battery stats service outside of activity manager service. File dataDir = Environment.getDataDirectory(); File systemDir = new File(dataDir, "system"); systemDir.mkdirs(); mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); mBatteryStatsService.getActiveStatistics().readLocked(); mBatteryStatsService.scheduleWriteToDisk(); mOnBattery = DEBUG_POWER ? true : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); mBatteryStatsService.getActiveStatistics().setCallback(this); mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); // User 0 is the first and only user that runs at boot. mStartedUsers.put(UserHandle.USER_OWNER, new UserState(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 = new CompatModePackages(this, systemDir, mHandler); mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); mRecentTasks = new RecentTasks(this); mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks); mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks); mProcessCpuThread = new Thread("CpuTracker") { @Override public void run() { while (true) { try { try { synchronized(this) { final long now = SystemClock.uptimeMillis(); long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; long nextWriteDelay = (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); }

这个构造器比较长,并且基本都是1些AMS平常工作的初始化,因此我们这里就不详细分析构造器的工作了,后面分析AMS的服务逻辑的时候我们在来分析对应的初始化工作。现在我们只要知道在AMS的构造器中做了这些工作就能够了:
1. 创建1堆类的对象,这些对象对AMS的平常工作来讲是必须的。
2. 初始化battery stats相干服务,AMS除负责activity的管理工作,还负责battery stats相干的工作
3. 初始化cpu统计相干服务,主要是启动1个线程,轮询处理。为AMS提供有关CPU运行统计方面数据做准备。
最落后行这个方法中最重要的操作,那就是将服务添加到ServiceManager中去,方面别的进程使用Binder查找到这个服务:

// Register it. mServices.add(service);

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

// Services that should receive lifecycle events. private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();

是的,mServices就是1个列表,这个列表中包括了它启动的所有SystemService类的服务,以便于后面调用它的生命周期方法。
接下来的操作就是回调我们前面提到的onStart方法:

// Start it. try { service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + name + ": onStart threw an exception", ex); }

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

@Override public void onStart() { mService.start(); }

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

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

这里有的人可能觉得奇怪,怎样这个start是1个private方法?上面使用mService.start();能访问吗?是的,可以访问的,虽然它是1个私有方法!这里可以参考本人的另外一篇文章:
http://blog.csdn.net/baniel01/article/details/51776120
这里的start方法很是简单,首先是调用Process类的removeAllProcessGroups方法移除所有的进程组,清空所有记录;然后就是启动ProcessCpuThread线程,mProcessCpuThread这个对象就是在刚才的构造器中初始化的;下面是发布BatteryStatsService,调用的是publish方法:
publish@BatteryStatsService.java

public 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中去,然后就是设置1些运行时参数,具体这些参数是甚么含义,读者可以自己分析1下BatteryStatsService的实现,这里我们就不详细分析了。
start方法的接下来的操作就是发布AppOpsService了,AppOpsService这个服务是提供android app ops服务的,甚么是android app ops服务呢?App Ops是在android 4.3中加入的1个权限管理框架,这个框架可让你自由地赋予或撤消某个app的权限,方便管理,下图是操作时候的界面:
这里写图片描述
关于android app ops,详见:
http://www.androidauthority.com/app-ops-need-know⑶24850/
下面是AppOpsService的publish方法:
publish@AppOpsService.java

public void publish(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的启动部份:

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

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

public ActivityManagerService getService() { return mService; }

而这里的mService就是在Lifecycle构造器中实例化的ActivityManagerService对象。
接下来在SystemServer.java中的操作就是调用AMS的setSystemServiceManager来将SystemServiceManager类的对象设置进去:
setSystemServiceManager@ActivityManagerService

public void setSystemServiceManager(SystemServiceManager mgr) { mSystemServiceManager = mgr; }

这里就只是将对象保存下来,以后会使用到。SystemServiceManager是1个创建,启动,和管理其他有关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. * * @param phase The boot phase to start. */ public void startBootPhase(final int phase) { if (phase <= mCurrentPhase) { throw new IllegalArgumentException("Next phase must be larger than previous"); } mCurrentPhase = phase; Slog.i(TAG, "Starting phase " + mCurrentPhase); final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); try { service.onBootPhase(mCurrentPhase); } catch (Exception ex) { throw new RuntimeException("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 the activity manager // initialize power management features. mActivityManagerService.initPowerManagement();

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

// Set up the Application instance for the system process and get started. mActivityManagerService.setSystemProcess();

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

public void setSystemProcess() { try { ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); ServiceManager.addService("meminfo", new MemBinder(this)); ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); ServiceManager.addService("dbinfo", new DbBinder(this)); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo", new CpuBinder(this)); } ServiceManager.addService("permission", new PermissionController(this)); ServiceManager.addService("processinfo", new ProcessInfoService(this)); ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS); mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); synchronized (this) { ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 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, false, null); updateOomAdjLocked(); } } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "Unable to find android system package", e); } }

就是这里了,我们看到这个方法上来的第1句就是ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);这句话就是我们想要找的,这句话的意思就是通过Binder向系统服务大管家ServiceManager(SM)注册我们的服务,这样android中的其他进程就能够通过context的getSystemService找到我们的服务了。这个方法中的接下来的代码让我们感觉AMS挺游手好闲的,它还分管着meminfo,gfxinfo,dbinfo,cpuinfo,permission,processinfo等业务,还真是忙啊!这里我们先不看这些业务,由于我们知道只有Activity的管理业务才是AMS的主页,其他的都只是副业而已了。
到这里,AMS的主体业务才算是启动终了。这里我们简单分析了1下android中的AMS的在开机进程中的启动流程,目的就是给大家关于AMS启动的1个清晰的结构,其实不是要四平八稳。个人感觉,android中的任何1个模块拿出来的话代码量都是巨大的,怎样从这些代码中找到android的设计的整体架构呢?最好的办法还是,先整体再模块,先抽象再具体。也就是先要知道整体的情况是甚么样的,然后再研究细节部份,不然的话很有可能会深陷android代码泥沼,不能自拔……

生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生