天天看点

Framework篇 - Application 的创建过程分析

Framework篇 - Application 的创建过程分析
本文源代码基于 Android 7.0。

system 进程和 app 进程都运行着一个或多个 app,每个 app 都会有一个对应的 Application 对象 (该对象和 LoadedApk 一一对应)。今天就来分析一下 Application 的创建过程,其实前面的文章已经有大体讲过,这边单独抽出一章来系统讲解下。

目录:

  1. system_server 进程创建 Application
  2. app 进程创建 Application

1. system_server 进程创建 Application

  • 1.1 SystemServer.createSystemContext():
/base/services/java/com/android/server/SystemServer.java

main() 方法中会调用 createSystemContext():

/**
     * 理解Application创建过程已介绍过createSystemContext()过程, 该过程会创建对象有ActivityThread,Instrumentation, ContextImpl,LoadedApk,Application。
     */
    private void createSystemContext() {
        // 创建system_server进程的上下文信息
        ActivityThread activityThread = ActivityThread.systemMain();
        mSystemContext = activityThread.getSystemContext();
        // 设置主题
        mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
    }
           
  • 1.2 ActivityThread
/base/core/java/android/app/ActivityThread.java
public final class ActivityThread {
    //创建ApplicationThread对象
    final ApplicationThread mAppThread = new ApplicationThread();
    final Looper mLooper = Looper.myLooper();
    final H mH = new H();
    //当前进程中首次初始化的app对象
    Application mInitialApplication;
    final ArrayList<Application> mAllApplications;
    //标记当前进程是否为system进程
    boolean mSystemThread = false;
    //记录system进程的ContextImpl对象
    private ContextImpl mSystemContext;

    final ArrayMap<String, WeakReference<LoadedApk>> mPackages;
    static Handler sMainThreadHandler;
    private static ActivityThread sCurrentActivityThread;

    ActivityThread() {
        mResourcesManager = ResourcesManager.getInstance();
    }
}
           

其中 mInitialApplication 的赋值过程分两种场景:

  • system_server 进程是由 ActivityThread.attach() 过程赋值;
  • 普通 app 进程是由是由 ActivityThread.handleBindApplication() 过程赋值;
  • 这是进程刚创建后 attach 到 system_server 后,便会 binder call 到 app 进程来执行该方法。

ActivityThread.currentApplication 返回的便是 mInitialApplication 对象。创建完 ActivityThread 对象,接下来执行 attach() 操作。

private void attach(boolean system) {
    sCurrentActivityThread = this;
    // 设置 mSystemThread 为 true
    mSystemThread = system; 
    if (!system) {
        ...
    } else { 
        // system 进程才执行该流程
        // 创建 Instrumentation
        mInstrumentation = new Instrumentation();
        ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
        mInitialApplication = context.mPackageInfo.makeApplication(true, null);
        // 回调 onCreate 方法
        mInitialApplication.onCreate();
        // ...
    }
}
           
  • 1.3 ContextImpl.createAppContext()
/base/core/java/android/app/ContextImpl.java
static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread,
                packageInfo, null, null, 0, null, null, Display.INVALID_DISPLAY);
       context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
                context.mResourcesManager.getDisplayMetrics());
        return context;
  }
           

根据 LoadedApk 对象来创建 ContextImpl,对于 system 进程 LoadedApk 对象取值为 mSystemContext,初始化 Application 信息。

  • 1.4 LoadedApk
/base/core/java/android/app/LoadedApk.java
public final class LoadedApk {
    private final ActivityThread mActivityThread;
    private ApplicationInfo mApplicationInfo;
    private Application mApplication;
    final String mPackageName;
    private final ClassLoader mBaseClassLoader;
    private ClassLoader mClassLoader;

    LoadedApk(ActivityThread activityThread) {
        mActivityThread = activityThread; //ActivityThread对象
        mApplicationInfo = new ApplicationInfo(); //创建ApplicationInfo对象
        mApplicationInfo.packageName = "android";
        mPackageName = "android";  //默认包名为"android"
        ...
        mBaseClassLoader = null;
        mClassLoader = ClassLoader.getSystemClassLoader(); //创建ClassLoader
        ...
    }
}
           

只有一个参数的 LoadedApk 构造方法只有 createSystemContext() 过程才会创建,其中 LoadedApk 初始化过程会创建ApplicationInfo 对象,且包名为"android"。 创建完 LoadedApk 对象,接下里创建 ContextImpl 对象。

  • 1.5 ContextImpl 初始化
class ContextImpl extends Context {
    final ActivityThread mMainThread;
    final LoadedApk mPackageInfo;
    private final IBinder mActivityToken;
    private final String mBasePackageName;
    private Context mOuterContext;
    // 缓存 Binder 服务
    final Object[] mServiceCache = SystemServiceRegistry.createServiceCache();

    private ContextImpl(ContextImpl container, ActivityThread mainThread, LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted, Display display, Configuration overrideConfiguration, int createDisplayWithId) {
        mOuterContext = this; //ContextImpl对象
        mMainThread = mainThread; // ActivityThread赋值
        mPackageInfo = packageInfo; // LoadedApk赋值
        mBasePackageName = packageInfo.mPackageName; //mBasePackageName 等于 “android”
        ...
    }
}
           

首次执行 getSystemContext,会创建 LoadedApk 和 contextImpl 对象,接下来利用刚创建的 LoadedApk 对象来创建新的ContextImpl 对象。 

  • 1.6 makeApplication()
​​​​​​​/base/core/java/android/app/LoadedApk.java
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
    //保证一个LoadedApk对象只创建一个对应的Application对象
    if (mApplication != null) {
        return mApplication;
    }

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application"; //system_server进程, 则进入该分支
    }

    //创建ClassLoader对象
    java.lang.ClassLoader cl = getClassLoader();
    if (!mPackageName.equals("android")) {
        initializeJavaContextClassLoader();
    }

    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    //创建Application对象
    Application app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
    appContext.setOuterContext(app);
    ...

    mActivityThread.mAllApplications.add(app);
    mApplication = app; //将刚创建的app赋值给mApplication
    ...
    return app;
}
           
  • 1.6 getClassLoader()
​​​​​​​/base/core/java/android/app/LoadedApk.java​​​​​​​ 
public ClassLoader getClassLoader() {
    synchronized (this) {
        if (mClassLoader != null) {
            return mClassLoader;
        }

        if (mPackageName.equals("android")) {
            if (mBaseClassLoader == null) {
                //创建Classloader对象
                mClassLoader = ClassLoader.getSystemClassLoader();
            } else {
                mClassLoader = mBaseClassLoader;
            }
            return mClassLoader;
        }

        // 当包名不为"android"的情况
        if (mRegisterPackage) {
            ActivityManagerNative.getDefault().addPackageDependency(mPackageName);
        }

        zipPaths.add(mAppDir);
        libPaths.add(mLibDir);
        apkPaths.addAll(zipPaths);
        ...

        if (mApplicationInfo.isSystemApp()) {
            isBundledApp = true;
            //对于系统app,则添加vendor/lib, system/lib库
            libPaths.add(System.getProperty("java.library.path"));
            ...
        }

        final String zip = TextUtils.join(File.pathSeparator, zipPaths);

        //获取ClassLoader对象
        mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip,
                mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath,
                libraryPermittedPath, mBaseClassLoader);
        return mClassLoader;
    }
}
           
  • 1.7 Application
​​​​​​​/base/core/java/android/app/Application.java

初始化:

// Application继承于ContextWrapper,装饰器模式,最终ContextWrapper里面调用ContextImpl实现,都是继承于Context
public class Application extends ContextWrapper implements ComponentCallbacks2 {
    /** @hide */
    // LoadedApk
    public LoadedApk mLoadedApk;

    public Application() {
        super(null);
    }
}
           

  attach():

final void attach(Context context) {
        attachBaseContext(context);
        mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
    }
           
  • 将新创建的 ContextImpl 对象保存到 Application 的父类成员变量 mBase;
  • 将新创建的 LoadedApk 对象保存到 Application 的父员变量 mLoadedApk;

2. app 进程创建 Application

  • 2.1 ActivityThread
/base/core/java/android/app/ActivityThread.java

main(): 

public static void main(String[] args) {
    ,,,
    ActivityThread thread = new ActivityThread();
    thread.attach(false);
    ,,,
}
           

这是运行在 app 进程,当进程由 zygote fork 后执行 ActivityThread 的 main() 方法。

attach():

private void attach(boolean system) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        //初始化RuntimeInit.mApplicationObject值
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        final IActivityManager mgr = ActivityManagerNative.getDefault();
        mgr.attachApplication(mAppThread); 
    } else {
        ...
    }
}
           

经过 Binder 调用,进入 system server 进程,执行 attachAppliaction 操作。

  • 2.2 ActivityManagerService
/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid);
        Binder.restoreCallingIdentity(origId);
    }
}

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
    ProcessRecord app;
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            app = mPidsSelfLocked.get(pid); // 根据pid获取ProcessRecord
        }
    }
    // ...

    ApplicationInfo appInfo = app.instrumentationInfo != null
            ? app.instrumentationInfo : app.info;

    thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
            profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
            app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
            isRestrictedBackupMode || !normalMode, app.persistent,
            new Configuration(mConfiguration), app.compat,
            getCommonServicesLocked(app.isolated),
            mCoreSettingsObserver.getCoreSettingsLocked());
    // ...
    return true;
}
           

system server 收到 attach 操作,然后再向新创建的进程执行 bindApplication(),里面会进入 ActivityThread,发送消息到 H,执行 handleBindApplication()。

  • 2.3 ActivityThread
/base/core/java/android/app/ActivityThread.java
private void handleBindApplication(AppBindData data) {
    mBoundApplication = data;
    Process.setArgV0(data.processName);//设置进程名
    ...
    //获取LoadedApk对象
    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
    ...

    // 创建ContextImpl上下文
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    ...

    try {
        // 此处data.info是指LoadedApk, 通过反射创建目标应用Application对象
        Application app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;
        ...
        mInstrumentation.onCreate(data.instrumentationArgs);
        //回调onCreate
        mInstrumentation.callApplicationOnCreate(app);

    } finally {
        StrictMode.setThreadPolicy(savedPolicy);
    }
}
           

在 handleBindApplication() 的过程中,会同时设置以下两个值:

  • LoadedApk.mApplication
  • ActivityThread.mInitialApplication
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
            CompatibilityInfo compatInfo) {
        return getPackageInfo(ai, compatInfo, null, false, true, false);
    }

    private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
            ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
            boolean registerPackage) {
        final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
        synchronized (mResourcesManager) {
            WeakReference<LoadedApk> ref;
            if (differentUser) {
                // Caching not supported across users
                ref = null;
            } else if (includeCode) {
                ref = mPackages.get(aInfo.packageName);
            } else {
                ref = mResourcePackages.get(aInfo.packageName);
            }

            LoadedApk packageInfo = ref != null ? ref.get() : null;
            if (packageInfo == null || (packageInfo.mResources != null
                    && !packageInfo.mResources.getAssets().isUpToDate())) {
                // 创建LoadedApk对象
                packageInfo =
                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
                            securityViolation, includeCode &&
                            (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);

                if (mSystemThread && "android".equals(aInfo.packageName)) {
                    packageInfo.installSystemApplicationInfo(aInfo,
                            getSystemContext().mPackageInfo.getClassLoader());
                }

                if (differentUser) {
                } else if (includeCode) {
                    // 将新创建的LoadedApk加入到mPackages
                    mPackages.put(aInfo.packageName,
                            new WeakReference<LoadedApk>(packageInfo));
                } else {
                    mResourcePackages.put(aInfo.packageName,
                            new WeakReference<LoadedApk>(packageInfo));
                }
            }
            return packageInfo;
        }
    }
           

创建 LoadedApk 对象,并将将新创建的 LoadedApk 加入到 mPackages。也就是说每个 app 都会创建唯一的 LoadedApk 对象,

此处 aInfo 来源于 ProcessRecord.info 变量,也就是进程中的第一个 app。

继续阅读