SystemServer进程创建系统上下文环境(mSystemContext)

上文中,在SystemServer.java的main方法,有一步是创建系统上下问环境,在本文中详细介绍一下。

SystemServer.java createSystemContext方法

    private void createSystemContext() {
        // 又看到了熟悉的内容了,哈哈哈  ActivityThread
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

        final Context systemUiContext = activityThread.getSystemUiContext();
        systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
    }

总结

这个方法比较简单:

  1. 获取ActivityThread的对象,调用的方法是ActivityThread.systemMain(),看这方法名就感觉这个对象是特意为系统而建的。
  2. 通过ActivityThread得到一个SystemContext
  3. 系统上下文环境一个主题,这个主题是啥还不清楚
  4. 获取系统UI上下文环境,然后设置主题

ActivityThread.java systemMain方法

    @UnsupportedAppUsage //这个注释看着像是说明下面这个方法不能给应用程序使用,只能系统使用
    public static ActivityThread systemMain() {
        // The system process on low-memory devices do not get to use hardware
        // accelerated drawing, since this can add too much overhead to the
        // process.
        //低内存设备上的系统进程无法使用硬件加速绘图,因为这会给进程增加过多的开销。
        if (!ActivityManager.isHighEndGfx()) { 
            ThreadedRenderer.disable(true);
        } else {
            ThreadedRenderer.enableForegroundTrimming();
        }
        ActivityThread thread = new ActivityThread();
        thread.attach(true, 0);
        return thread;
    }

总结

这个方法也简单

  1. 判断一下内存的大小,低内存的关闭硬件加速,高内存的打开硬件加速
  2. 创建一个ActivityThread对象
  3. 调用attach方法
  4. 返回ActivityThread对象

ActivityThread.java getSystemContext方法

    @UnsupportedAppUsage //只能系统调用
    public ContextImpl getSystemContext() {
        synchronized (this) {
            if (mSystemContext == null) {
                mSystemContext = ContextImpl.createSystemContext(this);
            }
            return mSystemContext;
        }
    }

总结

这方法就是单例模式返回一个系统级别的Context

ContextImpl.java createSystemContext方法

@UnsupportedAppUsage
    static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
                null, null);
        context.setResources(packageInfo.getResources());
        context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetrics());
        return context;
    }

总结

这个方法代码简单,不多说了,具体设置的那些参数是干嘛用的,这里没有必要展开了。

ContextImpl.java setTheme方法

    @Override
    public void setTheme(int resId) {
        synchronized (mSync) {
            if (mThemeResource != resId) {
                mThemeResource = resId;
                initializeTheme();
            }
        }
    }

总结

设置主题,没啥好说的

ContextImpl.java initializeTheme方法

private void initializeTheme() {
        if (mTheme == null) {
            mTheme = mResources.newTheme();
        }
        mTheme.applyStyle(mThemeResource, true);
    }

总结

设置主题,没啥好说的

ActivityThread.java attach

    // thread.attach(true, 0);这个是调用方式及参数
    @UnsupportedAppUsage
    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if (!system) {
           //...
        } else {
            //很明显,走的是这里

            // Don't set application object here -- if the system crashes,
            // we can't display an alert, we just want to die die die.
            //不要在这里设置应用程序对象-如果系统崩溃,我们将无法显示警报,我们只是想死掉。

            //设置应用名称
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this); // Instrumentation
                // getSystemContext().mPackageInfo 是createSystemContext方法创建的
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                //context.mPackageInfo 是 LoadedApk类的对象
                mInitialApplication = context.mPackageInfo.makeApplication(true, null); //Application
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }

        ViewRootImpl.ConfigChangedCallback configChangedCallback
                = (Configuration globalConfig) -> {
            synchronized (mResourcesManager) {
                // We need to apply this change to the resources immediately, because upon returning
                // the view hierarchy will be informed about it.
                //视图层级结构变更时会收到通知,这时候立即使用变更的resources 
                if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig,
                        null /* compat */)) {
                    updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(),
                            mResourcesManager.getConfiguration().getLocales());

                    // This actually changed the resources! Tell everyone about it.
                    if (mPendingConfiguration == null
                            || mPendingConfiguration.isOtherSeqNewer(globalConfig)) {
                        mPendingConfiguration = globalConfig;
                        sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
                    }
                }
            }
        };
        ViewRootImpl.addConfigCallback(configChangedCallback);
    }

总结

这个方法做的事情也比较多

  1. 设置应用名称 system_process
  2. 创建 Instrumentation 对象,并初始化mThread 的值
  3. 创建一个Application对象(mInitialApplication),并调用onCreate方法
  4. 创建了一个资源变更回调,添加到ViewRootImpl的静态变量中。(功能:在视图层级结构变更时会被调用,这时候立即使用变更的resources )

上面的方法中:

ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);

getSystemContext().mPackageInfo 是 LoadedApk类的对象, LoadedApk类的对象在createSystemContext方法创建的:

LoadedApk.java 构造方法之一

 LoadedApk(ActivityThread activityThread) {
        mActivityThread = activityThread;
        mApplicationInfo = new ApplicationInfo();
        mApplicationInfo.packageName = "android";    //重点 
        mPackageName = "android";   //重点 
        mAppDir = null;
        mResDir = null;
        mSplitAppDirs = null;
        mSplitResDirs = null;
        mSplitClassLoaderNames = null;
        mOverlayDirs = null;
        mDataDir = null;
        mDataDirFile = null;
        mDeviceProtectedDataDirFile = null;
        mCredentialProtectedDataDirFile = null;
        mLibDir = null;
        mBaseClassLoader = null;
        mSecurityViolation = false;
        mIncludeCode = true;
        mRegisterPackage = false;
        mResources = Resources.getSystem();
        mDefaultClassLoader = ClassLoader.getSystemClassLoader();
        mAppComponentFactory = createAppFactory(mApplicationInfo, mDefaultClassLoader);
        mClassLoader = mAppComponentFactory.instantiateClassLoader(mDefaultClassLoader,
                new ApplicationInfo(mApplicationInfo));
    }

总结

构造方法没啥好说的,重点看mApplicationInfo.packageName = "android"; 和 mPackageName = "android"; 后面用到了这两个变量。

继续往下:

LoadedApk.java makeApplication方法

    //context.mPackageInfo.makeApplication(true, null); 调用方式及参数
    @UnsupportedAppUsage
    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {//显然还是mApplication == null,后面会知道
            return mApplication;
        }

        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication");

        Application app = null;

        String appClass = mApplicationInfo.className;//从上面知道这个值是 “android”
        //显然forceDefaultAppClass的值是true
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application"; //走到这里
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            //根据前面知道 mPackageName 的值是“android”
            if (!mPackageName.equals("android")) {
                //不会走这里
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            //最终还是用mInstrumentation来创建 
            // appClass = "android.app.Application"; 
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            if (!mActivityThread.mInstrumentation.onException(app, e)) {
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                throw new RuntimeException(
                    "Unable to instantiate application " + appClass
                    + ": " + e.toString(), e);
            }
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app; //整个LoadApk类,给mApplication赋值的就只有这里,对应了前面判断语句

        if (instrumentation != null) { //传过来是null
            //...
        }

        // Rewrite the R 'constants' for all library apks. 重写R类的constants???
        SparseArray<String> packageIdentifiers = getAssets().getAssignedPackageIdentifiers();
        final int N = packageIdentifiers.size();
        for (int i = 0; i < N; i++) {
            final int id = packageIdentifiers.keyAt(i);
            if (id == 0x01 || id == 0x7f) {
                continue;
            }

            rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
        }

        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

        return app;
    }

总结

这个方法也做了挺多事情

  1. mApplication判空,整个LoadApk类,给mApplication赋值的就只有一处,在这里的时候mApplication还是null
  2. 把 appClass 的值设为"android.app.Application"
  3. 调用mActivityThread.mInstrumentation.newApplication创建Application,还是要用到Instrumentation,哈哈哈
  4. 把创建的系统Application添加到ActivityThread对象里面的mAllApplications这个列表里
  5. 最后是有一步重写R类的constants???这个没太看懂

Instrumentation.java newApplication方法

源码位置:frameworks\base\core\java\android\app

    //从前面知道 className == "android.app.Application"
    public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context);
        return app;
    }

总结

方法比较简单,不多说了

AppComponentFactory.java instantiateApplication方法

源码位置:frameworks\base\core\java\android\app

//从前面知道 className == "android.app.Application"
    public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
            @NonNull String className)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Application) cl.loadClass(className).newInstance();
    }

总结

方法也比较简单了,反射创建android.app.Application的对象。

results matching ""

    No results matching ""