一 概述
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.java
public @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.java
protected 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 调用。