App进程
创建Application的过程中会涉及的对象创建有:ActivityThread,ContextImpl,LoadedApk,Application,整体调用流程:
1、ActivityThread#main
首先由zygote fork后创建新的app进程,并执行ActivityThread的main方法
public static void main(String[] args) {
,,,
ActivityThread thread = new ActivityThread();
thread.attach(false);
,,,
}
2、ActivityThread#attach
private void attach(boolean system) {
sCurrentActivityThread = this;//保存当前的activityThread
mSystemThread = system;//是否是系统进程,在此为false
if (!system) {
ViewRootImpl.addFirstDrawHandler(new Runnable() {
@Override
public void run() {
ensureJitEnabled();
}
});
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
final IActivityManager mgr = ActivityManager.getService();
try {
//mAppThread是在创建ActivityThread的同时就已经同时创建的内部类实例
//final ApplicationThread mAppThread = new ApplicationThread();
mgr.attachApplication(mAppThread);///AMS的调用
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
...
}
3、AMS#attachApplication
转到 service 进程
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();//调用者进程pid
final long origId = Binder.clearCallingIdentity();
//thread对应ActivityThread的成员变量
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
4、AMS#attachApplicationLocked
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
...
ProcessRecord app;//当每个进程被创建的时候,都会记录在mPidsSelfLocked中,
// 对每个进程的跟踪缓存,具体可以看AMS中mPidsSelfLocked.put方法
long startTime = SystemClock.uptimeMillis();
if (pid != MY_PID && pid >= 0) {
synchronized (mPidsSelfLocked) {
app = mPidsSelfLocked.get(pid);
}
} else {
app = null;//如果app为null,后面直接return
}
...忽略一大堆逻辑
if (app.instr != null) {//当ProcessRecord中的Instrumention实例为null
//调用app进程中ApplicationThread#bindApplication,binder跨进程操作
thread.bindApplication(processName, appInfo, providers,
app.instr.mClass,
profilerInfo, app.instr.mArguments,
app.instr.mWatcher,
app.instr.mUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(getGlobalConfiguration()), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked(),
buildSerial);
} else {
...
}
}
5、ActivityThread::ApplicationThread#bindApplication
ApplicationThread是ActivityThread内部类,创建之初即被初始化 实例对象为 mAppThread
(此步骤已经发生在app进程)
public final void bindApplication(...) {
if (services != null) {
// Setup the service cache in the ServiceManager
ServiceManager.initServiceCache(services);
}
...
AppBindData data = new AppBindData();//创建appBindData对象,存储app相关的信息
...
sendMessage(H.BIND_APPLICATION, data);//发送BIND_APPLICATION消息到主线程中处理
H是ActivityThread中内部类,继承Handler,实例为mH
,用于处理各种主线程的回调消息
6、ActivityThread::H#handleMessage
handleMessage -> BIND_APPLICATION -> ActivityThread#handleBindApplication
private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
Process.setArgV0(data.processName);//设置进程名
...
//1.创建LoadedApk对象
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
...
// 2.创建ContextImpl上下文
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
...
// 3.创建instrumentation
...
try {
// 4.创建应用Application
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
mInstrumentation.onCreate(data.instrumentationArgs);
//回调onCreate
mInstrumentation.callApplicationOnCreate(app);
} finally {
StrictMode.setThreadPolicy(savedPolicy);
}
}
6.1、创建 LoadedApk
ActivityThread#getPackageInfoNoCheck -> ActivityThread#getPackageInfo
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
boolean registerPackage) {
...
synchronized (mResourcesManager) {
WeakReference<LoadedApk> ref;
....
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 (includeCode) { //每个App的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.
6.2、创建ContextImpl
ContextImpl#createAppContext
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) {
if (packageInfo == null) throw new IllegalArgumentException("packageInfo");
ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0,
null);
context.setResources(packageInfo.getResources());
return context;
}
6.3、创建Instrumentation
通过反射创建
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate instrumentation "
+ data.instrumentationName + ": " + e.toString(), e);
}
....
mInstrumentation.init(this, instrContext, appContext, component,
data.instrumentationWatcher, data.instrumentationUiAutomationConnection)
6.4、创建Application对象
- LoadedApk#makeApplication
public Application makeApplication(boolean forceDefaultAppClass,
Instrumentation instrumentation) {
if (mApplication != null) {
return mApplication;
}
Application app = null;
String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
appClass = "android.app.Application";
}
try {
java.lang.ClassLoader cl = getClassLoader();
if (!mPackageName.equals("android")) {
}
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(
cl, appClass, appContext);
appContext.setOuterContext(app);
} catch (Exception e) {
...
}
- Instrumentation#newApplication
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();//反射创建
app.attach(context);
return app;
}
- Application#attach -> ContextWrapper#attachBaseContext
final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
�6.5、Application周期回调
Instrumentation#callApplicationOnCreate
public void callApplicationOnCreate(Application app) {
app.onCreate();
}