
本文共 17031 字,大约阅读时间需要 56 分钟。
一 概述
system_server 进程和 app 进程都运行着一个或多个 app,每个 app 都会有一个对应的 Application 对象(该对象跟 LoadedApk 一一对应)。下面分别分析这两种进程创建 Application 的过程:
- system_server 进程
- app 进程
二 system_server进程
2.1 SystemServer.run
frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer { private static final String TAG = "SystemServer"; ...... public static void main(String[] args) { new SystemServer().run(); } ...... private void run() { try { ...... createSystemContext(); ...... } finally { ...... } ...... }}private void createSystemContext() { ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(DEFAULT_SYSTEM_THEME); final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);}
2.2 ActivityThread.systemMain
frameworks/base/core/java/android/app/ActivityThread.java
public static ActivityThread systemMain() { ...... ActivityThread thread = new ActivityThread(); thread.attach(true, 0); return thread;}public final class ActivityThread extends ClientTransactionHandler { //创建ApplicationThread对象 final ApplicationThread mAppThread = new ApplicationThread(); final Looper mLooper = Looper.myLooper(); final H mH = new H(); //当前进程中首次初始化的app对象 Application mInitialApplication; final ArrayList<Application> mAllApplications = new ArrayList<Application>(); //标记当前进程是否为system进程 boolean mSystemThread = false; //记录system进程的ContextImpl对象 private ContextImpl mSystemContext; private ContextImpl mSystemUiContext; final ArrayMap<String, WeakReference<LoadedApk>> mPackages = new ArrayMap<>(); static volatile Handler sMainThreadHandler;//set once in main() private static volatile 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() 操作。
2.3 ActivityThread.attach
private void attach(boolean system, long startSeq) { sCurrentActivityThread = this; mSystemThread = system; //设置mSystemThread为true if (!system) { ...... } else { //system进程才执行该流程 try { //创建Instrumentation mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); } catch (Exception e) { ...... } ...... }}
2.3.1 Application.onCreate
public void onCreate() { //方法为空, 一般由其子类实现该方法}
2.4 ContextImpl.createAppContext
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { return createAppContext(mainThread, packageInfo, null);}static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo, String opPackageName) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null, opPackageName); context.setResources(packageInfo.getResources()); return context;}
创建 ContextImpl 对象有多种方法,常见的有:
createSystemContext(ActivityThread mainThread)createAppContext(ActivityThread mainThread, LoadedApk packageInfo)createApplicationContext(ApplicationInfo application, int flags)createPackageContext(String packageName, int flags)createSystemUiContext(ContextImpl systemContext)createActivityContext(ActivityThread mainThread, ......)
此处,packageInfo 是 getSystemContext().mPackageInfo,getSystemContext() 获取的 ContextImpl 对象, 其成员变量 mPackageInfo 便是 LoadedApk 对象。所以先来看看 getSystemContext() 过程。
2.4.1 ActivityThread.getSystemContext
public ContextImpl getSystemContext() { synchronized (this) { if (mSystemContext == null) { mSystemContext = ContextImpl.createSystemContext(this); } return mSystemContext; }}
单例模式创建 mSystemContext 对象
2.4.2 ContextImpl.createSystemContext
static ContextImpl createSystemContext(ActivityThread mainThread) { LoadedApk packageInfo = new LoadedApk(mainThread); ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null, null); ...... return context;}
2.4.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 = mAppComponentFactory.instantiateClassLoader( mDefaultClassLoader, new ApplicationInfo(mApplicationInfo)); ...... }}
只有一个参数的 LoadedApk 构造方法只有 createSystemContext() 过程才会创建, 其中 LoadedApk 初始化过程会创建 ApplicationInfo 对象,且包名为 “android”。 创建完 LoadedApk 对象,接下来创建 ContextImpl 对象。
2.4.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, ......) { mOuterContext = this; //ContextImpl对象 mMainThread = mainThread; // ActivityThread赋值 mPackageInfo = packageInfo; // LoadedApk赋值 mBasePackageName = packageInfo.mPackageName; //mBasePackageName等于“android” ...... }}
首次执行 getSystemContext,会创建 LoadedApk 和 contextImpl 对象,接下来利用刚创建的 LoadedApk 对象来创建新的 ContextImpl 对象。
2.5 LoadedApk.makeApplication
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { //保证一个LoadedApk对象只创建一个对应的Application对象 if (mApplication != null) { return mApplication; } ...... Application app = null; String appClass = mApplicationInfo.className; if (forceDefaultAppClass || (appClass == null)) { //system_server进程, 则进入该分支 appClass = "android.app.Application";//设置应用类名 } try { java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals("android")) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "initializeJavaContextClassLoader"); initializeJavaContextClassLoader(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } //创建ContextImpl对象 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); //创建Application对象, 并将appContext attach到新创建的Application app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); } catch (Exception e) { ...... } mActivityThread.mAllApplications.add(app); mApplication = app;//将刚创建的app赋值给mApplication if (instrumentation != null) { try { //调用application的OnCreate方法 instrumentation.callApplicationOnCreate(app); } catch (Exception e) { ...... } } ...... return app;}
2.6 LoadedApk.initializeJavaContextClassLoader
private void initializeJavaContextClassLoader() { IPackageManager pm = ActivityThread.getPackageManager(); android.content.pm.PackageInfo pi; try { pi = pm.getPackageInfo(mPackageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, UserHandle.myUserId()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } if (pi == null) { ...... } 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; Thread.currentThread().setContextClassLoader(contextClassLoader);}
2.7 Instrumentation.newApplication
public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, ...... { Application app = getFactory(context.getPackageName()) .instantiateApplication(cl, className); app.attach(context); return app;}private AppComponentFactory getFactory(String pkg) { if (pkg == null) { Log.e(TAG, "No pkg specified, disabling AppComponentFactory"); return AppComponentFactory.DEFAULT; } if (mThread == null) { ...... return AppComponentFactory.DEFAULT; } LoadedApk apk = mThread.peekPackageInfo(pkg, true); // This is in the case of starting up "android". if (apk == null) apk = mThread.getSystemContext().mPackageInfo; return apk.getAppFactory();}AppComponentFactory.javapublic @NonNull Application instantiateApplication(ClassLoader cl, @NonNull String className) throws InstantiationException, ...... { return (Application) cl.loadClass(className).newInstance();}
2.8 Application.attach
final void attach(Context context) { attachBaseContext(context); mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;} Application父类ContextWraper.javaprotected void attachBaseContext(Context base) { if (mBase != null) { throw new IllegalStateException("Base context already set"); } mBase = base;}
- 将新创建的 ContextImpl 对象保存到 Application 父类成员变量 mBase
- 将新创建的 LoadedApk 对象保存到 Application 的父员变量 mLoadedApk
三 App进程
3.1 ActivityThread.main
public static void main(String[] args) { Looper.prepareMainLooper(); ...... ActivityThread thread = new ActivityThread(); thread.attach(false, startSeq); ...... Looper.loop();}
这是运行在 app 进程,当进程由 zygote fork 后执行 ActivityThread 的 main 方法,注意 attach 函数的参数,这里为 false。
3.2 ActivityThread.attach
private void attach(boolean system, long startSeq) { sCurrentActivityThread = this; mSystemThread = system; //设置mSystemThread为true if (!system) { //app进程 ...... final IActivityManager mgr = ActivityManager.getService(); try { mgr.attachApplication(mAppThread, startSeq); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } ...... } else { //system进程才执行该流程 ...... }}
经过 Binder 调用,进入 system_server 进程,执行 attachApplication。
3.3 AMS.attachApplication
public final void attachApplication(IApplicationThread thread, long startSeq) { if (thread == null) { throw new SecurityException("Invalid application interface"); } synchronized (this) { int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid, callingUid, startSeq); Binder.restoreCallingIdentity(origId); }}private boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) { ProcessRecord app; ...... try { ...... if (app.isolatedEntryPoint != null) { ...... } else if (instr2 != null) { // 绑定App进程 thread.bindApplication(processName, appInfo, providers, instr2.mClass, profilerInfo, instr2.mArguments, instr2.mWatcher, instr2.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.isPersistent(), new Configuration(app.getWindowProcessController().getConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial, autofillOptions, contentCaptureOptions); } else { ...... } ...... } catch (Exception e) { ...... return false; } ...... return true;}
3.3 ActivityThread.bindApplication
public final void bindApplication(String processName, ......) { ......// 封装App进程绑定数据AppBindData AppBindData data = new AppBindData(); data.processName = processName; data.appInfo = appInfo; data.providers = providers; data.instrumentationName = instrumentationName; data.instrumentationArgs = instrumentationArgs; data.instrumentationWatcher = instrumentationWatcher; data.instrumentationUiAutomationConnection = instrumentationUiConnection; data.debugMode = debugMode; data.enableBinderTracking = enableBinderTracking; data.trackAllocation = trackAllocation; data.restrictedBackupMode = isRestrictedBackupMode; data.persistent = persistent; data.config = config; data.compatInfo = compatInfo; data.initProfilerInfo = profilerInfo; data.buildSerial = buildSerial; data.autofillOptions = autofillOptions; data.contentCaptureOptions = contentCaptureOptions; sendMessage(H.BIND_APPLICATION, data);}
3.4 ActivityThread.handleBindApplication
private void handleBindApplication(AppBindData data) { // 从AppBindData中取出InstrumentationInfo信息 final InstrumentationInfo ii; if (data.instrumentationName != null) { ii = new ApplicationPackageManager(null, getPackageManager()).getInstrumentationInfo( data.instrumentationName, 0); mInstrumentationPackageName = ii.packageName; mInstrumentationAppDir = ii.sourceDir; ...... } //获取LoadedApk对象 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); // 创建Context final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); // InstrumentationInfo对象非空 // 从InstrumentationInfo中取出各参数, 基于此创建和初始化Instrumentation if (ii != null) { ApplicationInfo instrApp = getPackageManager() .getApplicationInfo(ii.packageName, 0, UserHandle.myUserId()); if (instrApp == null) { instrApp = new ApplicationInfo(); } // 将InstrumentationInfo里的参数拷贝到ApplicationInfo对象 ii.copyTo(instrApp); instrApp.initForUser(UserHandle.myUserId()); final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); final ContextImpl instrContext = ContextImpl.createAppContext(this, pi, appContext.getOpPackageName()); final ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl .loadClass(data.instrumentationName.getClassName()).newInstance(); final ComponentName component = new ComponentName(ii.packageName, ii.name); mInstrumentation.init(this, instrContext, ......); } else { // 初始化Instrumentation mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); } //创建Application对象 Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; mInstrumentation.onCreate(data.instrumentationArgs); //调用Application.onCreate()方法. mInstrumentation.callApplicationOnCreate(app); ......}
在 handleBindApplication() 的过程中,会创建 Application 并调用其 onCreate 方法
四 总结
system_server 进程
其 application 创建过程都创建对象有 ActivityThread,Instrumentation,ContextImpl,LoadedApk,Application。 流程图如下:
app 进程
其 application 创建过程都创建对象有 ActivityThread,ContextImpl,LoadedApk,Application。 流程图如下:
App 进程的 Application 创建过程,跟 system 进程的核心逻辑都差不多。只是 app 进程多了两次 binder 调用。
发表评论
最新留言
关于作者
