这段时间在研究360 Android插件(DroidPlugin),在网上查找AMS资料,发现都比较老,所以,自己在Android 6.0的基础上走了一遍。
- 第一条线、同其他服务一样,将分析SystemServer中的AMS的调用轨迹;
- 第二条线、以am命令启动一个Activity为例,分析应用进程的创建、Activity的启动,以及他们和AMS之间的交互等知识;
- 第三条线、以Broadcast为例,分析AMS中Broadcast的相关处理流程;
- 第四条线、以Service为例,分析AMS中Service的相关处理流程;
- 第五条线、以一个Crash的应用进程为出发点,分析AMS如何打理该应用进程“身后事”。
一、AMS由SystemServer的ServerThread线程创建,代码如下:
public final class SystemServer {
//zygote的主入口
public static void main(String[] args) {
new SystemServer().run();
}
public SystemServer() {
// Check for factory test mode.
mFactoryTestMode = FactoryTest.getMode();
}
private void run() {
......
//加载本地系统服务库,并进行初始化
System.loadLibrary("android_servers");
nativeInit();
// 1、创建系统上下文
createSystemContext();
//初始化SystemServiceManager对象,下面的系统服务开启都需要调用SystemServiceManager.startService(Class<T>),这个方法通过反射来启动对应的服务
mSystemServiceManager = new SystemServiceManager(mSystemContext);
//开启服务
try {
startBootstrapServices();
startCoreServices();
startOtherServices();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
}
......
}
/*初始化系统上下文对象mSystemContext,并设置默认的主题,mSystemContext实际上是一个ContextImpl对象。 *调用ActivityThread.systemMain()的时候,会调用ActivityThread.attach(true),而在attach()里面,则创建了Application对象, *并调用了Application.onCreate()。 */
private void createSystemContext() {
ActivityThread activityThread = ActivityThread.systemMain();
mSystemContext = activityThread.getSystemContext();
mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar);
}
//在这里开启了几个核心的服务,因为这些服务之间相互依赖,所以都放在了这个方法里面。
private void startBootstrapServices() {
......
//初始化ActivityManagerService
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
//初始化PowerManagerService,因为其他服务需要依赖这个Service,因此需要尽快的初始化
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// 初始化DisplayManagerService
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
// 2、systemServer进程加载到AMS中,并被它管理
mActivityManagerService.setSystemProcess();
......
}
private void startOtherServices() {
// 3、将SettingProvider放到SystemServer进程中来运行
mActivityManagerService.installSystemProviders();
// 4、AMS是系统的核心服务,只有它准备好了,才能调用其他服务的SystemReady
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
try {
startSystemUi(context); // 启动systemUi,如此,状态栏就准备好了
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
Watchdog.getInstance().start(); // 启动watchdog
}
});
}
}
经过上面这些步骤,我们的ActivityManagerService对象已经创建好了,并且完成了成员变量初始化。而且在这之前,调用createSystemContext()创建系统上下文的时候,也已经完成了mSystemContext和ActivityThread的创建。注意,这是系统进程开启时的流程,在这之后,会开启系统的Launcher程序,完成系统界面的加载与显示。
二、AMS的构造函数分析
public ActivityManagerService(Context systemContext) {
File dataDir = Environment.getDataDirectory(); // 指向 /data/ 目录
File systemDir = new File(dataDir, "system"); // 指向 /data/system/目录
systemDir.mkdirs(); // 创建/data/system/目录
try {
if (SystemProperties.get("ro.have_aee_feature").equals("1")) {
exceptionLog = new ExceptionLog();
}
} catch (Exception e) {
// AEE disabled or failed to allocate AEE object, no need to show message
}
// 创建mBatteryStatsService(BSS)和
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();
// 获取OpenGL版本
GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
// mConfiguration 类型为Configuration,用于描述资源文件的配置属性,例如,字体、语言等。
mConfiguration.setToDefaults();
mConfiguration.setLocale(Locale.getDefault());
mConfigurationSeq = mConfiguration.seq = 1;
/* 用来收集每ANRs,进程的CPU使用电池的统计等信息 访问它时,必须获得此对象的锁。 注:此锁将于在长时间操作(拖网 通过/proc所有过程),所以它不应该得到的 任何关键路径,如举行主活动管理器锁的时候。 */
mProcessCpuTracker.init();
/* 解析/data/system/packages-compat.xml文件,该文件用于存储那些需要考虑屏幕尺寸的APK信息, 可以参考AndroidManifest.xml中的compatible-screens相关说明, 当APK所运行的设备不满足要求时,AMS会根据设置的参数以采用屏幕兼容的方式运行它 */
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);
// 创建新的进程,用于定时更新系统信息,跟mProcessCpuTracker交互
mProcessCpuThread = new Thread("CpuTracker") {
@Override
public void run() {
while (true) { }
}
};
}
三、ActivityThread.systemMain 函数分析
一)、zygote–>SystemServer–>AMS和ActivityThread–>ActivityManager 解释:
1、App(ActivityThread进程)和AMS(SystemServer进程)还有zygote进程分属于三个独立的进程
2、App与AMS通过Binder进行IPC通信,AMS(SystemServer进程)与zygote通过Socket进行IPC通信。
3、那么AMS有什么用呢?
如果想打开一个App的话,需要AMS去通知zygote进程,除此之外,其实所有的Activity的开启、暂停、关闭都需要AMS来控制,所以我们说,AMS负责系统中所有Activity的生命周期。
4、AMS和ActivityThread关系
在Android系统中,任何一个Activity的启动都是由AMS和应用程序进程(主要是ActivityThread)相互配合来完成的。AMS服务统一调度系统中所有进程的Activity启动,而每个Activity的启动过程则由其所属的进程具体来完成。
public static ActivityThread systemMain() {
if (!ActivityManager.isHighEndGfx()) {
HardwareRenderer.disable(true); // 禁止硬件加速
} else {
HardwareRenderer.enableForegroundTrimming();
}
// 创建一个ActivityThread对象
ActivityThread thread = new ActivityThread();
thread.attach(true); // 调用attach函数,参数为true
return thread;
}
二)、ActivityThread在SystemServer中的作用
1、在PKMS分析中提到framework-res.apk,这个APK除了包含资源文件外,还包含一些Activity(如关机对话框),这些Activity实际上运行在SystemServer进程中,
从这个角度看systemServer只一个特殊的应用进程。
2、通过ActivityThread可以把Android系统提供的组件之间的交互机制和交互接口(如利用Context提供的API)也扩展到systemServer中使用。
四、attach函数分析
private void attach(boolean system) {
sCurrentActivityThread = this;
mSystemThread = system; // 判断是否为系统进程
if (!system) { // 应用进程的处理流程
......
} else { //系统进程的处理流程,该情况只在systemServer中处理
// 设置DDMS时看到的systemserver进程名
android.ddm.DdmHandleAppName.setAppName("system_process",
UserHandle.myUserId());
try {
// Instrumentation类出现了
mInstrumentation = new Instrumentation();
// 初始化context,注意参数getSystemContext().mPackageInfo
ContextImpl context = ContextImpl.createAppContext(
this, getSystemContext().mPackageInfo);
//makeApplication 方法中创建Application对象,一个进程支持多个Application
// mInitialApplication用于保存Application对象
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
mInitialApplication.onCreate(); //调用Application的Oncreate()
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate Application():" + e.toString(), e);
}
}
// 注册Configuration变化时的回调通知
ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
@Override
public void onConfigurationChanged(Configuration newConfig) {
}
@Override
public void onLowMemory() {}
@Override
public void onTrimMemory(int level) {}
});
}
一)、attach()中出现了几个重要成员,Instrumentrain类、Application类和Context类,他们的作用如下:
1、Instrumentrain 是一个工具类,当他被启用时,系统先创建他,再通过他来创建其他组件。另外,系统和组件之间的交互也是通过Instrumentrain来传递,这样,Instrumentrain就能检测系统和这些组件的交互情况,在实际使用中,我们可以创建Instrumentrain的派生类来进行相应的处理。
2、
1)、Application类保存了一个全局的application状态,Application由AndroidManifest.xml中的标签声明;
2)、在实际使用中需定义Application派生类;
3)、Application是Android中的一个概念,可以理解为一种容器,其内部包含四大组件,一个进程可以运行多个Application
3、Context是一个接口,通过他可以获取并操作Application对应的资源、类,甚至包含于Application中的四大组件
五、getSystemContext函数分析