Android 6.0 AMS分析的第一条线:SystemServer中的AMS的调用轨迹

这段时间在研究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函数分析

    原文作者:yaoming168
    原文地址: https://blog.csdn.net/yaoming168/article/details/51991570
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞