Application创建过程-1
一、概述
system进程和app进程都运行着一个或多个app,每个app都会有一个对应的 Application对象#######(该对象 跟 LoadedApk 一一对应)。下面分别以下两种进程创建Application的过程:
1. system_server进程;
2. app进程;
二、system_server进程
2.1 SystemServer.run
[-> SystemServer.java]
public final class SystemServer { private void run() { ... createSystemContext(); //[见2.2] startBootstrapServices(); //开始启动服务 ... } }
2.2 createSystemContext
[-> SystemServer.java]
private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); //[见2.3] mSystemContext = activityThread.getSystemContext(); //[见2.6.1] mSystemContext.setTheme(android.R.style.Theme_DeviceDefault_Light_DarkActionBar); }
2.3 AT.systemMain
[-> ActivityThread.java]
public static ActivityThread systemMain() { ... ActivityThread thread = new ActivityThread(); //[见2.4] thread.attach(true); //[见2.5] return thread; }
2.4 AT初始化
[-> 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 的赋值过程分两种场景:
(1) system_server 进程是由 ActivityThread.attach() 过程赋值;
(2) 普通 app 进程是由是由 ActivityThread.handleBindApplication() 过程赋值;这是进程刚创建后 attach 到 system_server 后, 便会 binder call 到 app 进程来执行该方法.
AT.currentApplication 返回的便是 mInitialApplication 对象。创建完 ActivityThread 对象,接下来执行 attach() 操作。
2.5 AT.attach
[-> ActivityThread.java]
private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; //设置mSystemThread为true if (!system) { ... } else { //system进程才执行该流程 //创建Instrumentation mInstrumentation = new Instrumentation(); //[见小节2.6] ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo); //[见小节2.7] mInitialApplication = context.mPackageInfo.makeApplication(true, null); //回调onCreate方法[见小节2.5.1] mInitialApplication.onCreate(); ... } }
attach 的主要功能:
(1) 根据 LoadedApk 对象来创建 ContextImpl,对于 system 进程 LoadedApk 对象取值为 mSystemContext;
(2) 初始化 Application 信息。
2.5.1 onCreate
[-> Application.java]
public void onCreate() { ... //该方法为空, 一般地都是由其子类所覆写该方法 }
2.6 CI.createAppContext
[-> ContextImpl.java]
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { //[见小节2.6.4] return new ContextImpl(null, mainThread, packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY); }
创建 ContextImpl 对象有多种方法,常见的有:
createSystemContext(ActivityThread mainThread) createAppContext(ActivityThread mainThread, LoadedApk packageInfo) createApplicationContext(ApplicationInfo application, int flags) createPackageContext(String packageName, int flags)
此处,packageInfo 是 getSystemContext().mPackageInfo,getSystemContext() 获取的 ContextImpl 对象, 其成员变量 mPackageInfo 便是 LoadedApk 对象。所以先来看看 getSystemContext() 过程。
2.6.1 AT.getSystemContext
public ContextImpl getSystemContext() { synchronized (this) { if (mSystemContext == null) { mSystemContext = ContextImpl.createSystemContext(this); } return mSystemContext; } }
单例模式创建 mSystemContext 对象。
2.6.2 CI.createSystemContext
static ContextImpl createSystemContext(ActivityThread mainThread) { //创建LoadedApk对象 【见小节2.6.3】 LoadedApk packageInfo = new LoadedApk(mainThread); // 创建ContextImpl【见小节2.6.4】 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, false, null, null, Display.INVALID_DISPLAY); ... return context; }
2.6.3 LoadedApk初始化
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 对象。
2.6.4 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 对象。
2.7 makeApplication
[-> 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对象【见小节2.8】 java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals("android")) { initializeJavaContextClassLoader(); //[见小节2.9] } ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); //创建Application对象[见2.10] Application app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext); appContext.setOuterContext(app); ... mActivityThread.mAllApplications.add(app); mApplication = app; //将刚创建的app赋值给mApplication ... return app; }
2.8 getClassLoader
[-> 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) { //【见小节2.8.1】 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对象【见小节2.8.2】 mClassLoader = ApplicationLoaders.getDefault().getClassLoader(zip, mApplicationInfo.targetSdkVersion, isBundledApp, librarySearchPath, libraryPermittedPath, mBaseClassLoader); return mClassLoader; } }
2.8.1 AMS.addPackageDependency
public void addPackageDependency(String packageName) { synchronized (this) { int callingPid = Binder.getCallingPid(); if (callingPid == Process.myPid()) { return; } ProcessRecord proc; synchronized (mPidsSelfLocked) { //查询的进程 proc = mPidsSelfLocked.get(Binder.getCallingPid()); } if (proc != null) { if (proc.pkgDeps == null) { proc.pkgDeps = new ArraySet<String>(1); } //将目标包名加入到调用者进程的pkgDeps proc.pkgDeps.add(packageName); } } }
2.8.2 AL.getClassLoader
[-> ApplicationLoaders.java]
public ClassLoader getClassLoader(String zip, int targetSdkVersion, boolean isBundled, String librarySearchPath, String libraryPermittedPath, ClassLoader parent) { //获取父类的类加载器 ClassLoader baseParent = ClassLoader.getSystemClassLoader().getParent(); synchronized (mLoaders) { if (parent == null) { parent = baseParent; } if (parent == baseParent) { ClassLoader loader = mLoaders.get(zip); if (loader != null) { return loader; } //创建PathClassLoader对象 PathClassLoader pathClassloader = PathClassLoaderFactory.createClassLoader( zip, librarySearchPath, libraryPermittedPath, parent, targetSdkVersion, isBundled); mLoaders.put(zip, pathClassloader); return pathClassloader; } PathClassLoader pathClassloader = new PathClassLoader(zip, parent); return pathClassloader; } }
2.9 initializeJavaContextClassLoader
[-> LoadedApk.java]
private void initializeJavaContextClassLoader() { IPackageManager pm = ActivityThread.getPackageManager(); android.content.pm.PackageInfo pi; pi = pm.getPackageInfo(mPackageName, 0, UserHandle.myUserId()); boolean sharedUserIdSet = (pi.sharedUserId != null); boolean processNameNotDefault = (pi.applicationInfo != null && !mPackageName.equals(pi.applicationInfo.processName)); boolean sharable = (sharedUserIdSet || processNameNotDefault); ClassLoader contextClassLoader = (sharable) ? new WarningContextClassLoader() : mClassLoader; //设置当前线程的Context ClassLoader Thread.currentThread().setContextClassLoader(contextClassLoader); }
2.10 newApplication
[-> Instrumentation.java]
public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { return newApplication(cl.loadClass(className), context); }
此处 cl 便是前面 getClassLoader() 所获取的 PathClassLoader 对象。通过其方法 loadClass() 来加载目标 Application 对象;
2.10.1 newApplication
[-> Instrumentation.java]
static public Application newApplication(Class<?> clazz, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Application app = (Application)clazz.newInstance(); //【见小节2.10.2】 app.attach(context); //【见小节2.10.3】 return app; }
2.10.2 Application初始化
[-> Application.java]
public class Application extends ContextWrapper implements ComponentCallbacks2 { public LoadedApk mLoadedApk; public Application() { super(null); } }
2.10.3 App.attach
[-> Application.java]
final void attach(Context context) { attachBaseContext(context); //Application的mBase mLoadedApk = ContextImpl.getImpl(context).mPackageInfo; }
该方法主要功能:
(1) 将新创建的 ContextImpl 对象保存到 Application 的父类成员变量 mBase;
(2) 将新创建的 LoadedApk 对象保存到 Application 的父员变量 mLoadedApk;
三. App进程
3.1 ActivityThread.main
[-> ActivityThread.java]
public static void main(String[] args) { ,,, ActivityThread thread = new ActivityThread(); thread.attach(false); ,,, }
这是运行在app进程,当进程由 zygote fork 后执行 ActivityThread 的 main 方法。
3.2 AT.attach
[-> ActivityThread.java]
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); //[见小节3.3] } else { ... } }
经过binder调用,进入system_server进程,执行如下操作。
3.3 AMS.attachApplication
[-> 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; //[见流程3.4] 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 操作, 然后再向新创建的进程执行 handleBindApplication() 过程:
3.4 AT.handleBindApplication
[-> ActivityThread.java ::H]
当主线程收到 H.BIND_APPLICATION,则调用 handleBindApplication
private void handleBindApplication(AppBindData data) { mBoundApplication = data; Process.setArgV0(data.processName); //设置进程名 ... //获取LoadedApk对象[见小节3.5] data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); ... // 创建ContextImpl上下文[2.6.4] final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); ... try { // 此处data.info是指LoadedApk, 通过反射创建目标应用Application对象[见小节2.7] Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; ... mInstrumentation.onCreate(data.instrumentationArgs); //回调onCreate [见小节3.4.1] mInstrumentation.callApplicationOnCreate(app); } finally { StrictMode.setThreadPolicy(savedPolicy); } }
在 handleBindApplication() 的过程中,会同时设置以下两个值:
(1) LoadedApk.mApplication
(2) ActivityThread.mInitialApplication
3.4.1 onCreate
[-> Instrumentation.java]
public void callApplicationOnCreate(Application app) { app.onCreate(); }
3.5 getPackageInfoNoCheck
[-> ActivityThread.java]
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) { ref = null; } else if (includeCode) { ref = mPackages.get(aInfo.packageName); //从mPackages查询 } else { ... } 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)) { ... } if (differentUser) { ... } else if (includeCode) { //将新创建的LoadedApk加入到mPackages mPackages.put(aInfo.packageName, new WeakReference<LoadedApk>(packageInfo)); } else { ... } } return packageInfo; } }
创建 LoadedApk 对象,并将新创建的 LoadedApk 加入到 mPackages. 也就是说每个app都会创建唯一的 LoadedApk 对象. 此处 aInfo 来源于 ProcessRecord.info 变量, 也就是进程中的第一个app.
四. 总结
1. system_server进程
其 application 创建过程都创建对象有 ActivityThread,Instrumentation, ContextImpl,LoadedApk,Application。流程图如下:
2. app进程
其 application 创建过程都创建对象有 ActivityThread,ContextImpl,LoadedApk,Application。 流程图如下:
App进程的 Application 创建过程,跟system进程的核心逻辑都差不多。只是app进程多了两次binder调用。
参考:
理解Application创建过程: http://gityuan.com/2017/04/02/android-application/
posted on 2023-08-14 17:30 Hello-World3 阅读(22) 评论(0) 编辑 收藏 举报