前言
本文假设你已经了解了android的Binder机制,如果你还未了解相关知识,就没必要阅读本文了。
正文
一个进程可以运行多个app(mainfest中通过process:name可以指定),每个app都有一个Application对象,简单介绍下非系统进程创建Application的过程。
我们先看下ActivityMangerService(AMS)里创建进程的部分代码
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
app.info.dataDir, entryPointArgs);
.....
this.mPidsSelfLocked.put(startResult.pid, app);
.....
返回的startResult里有个个成员变量pid,这个值是进程的id,AMS把这个值和ProcessRecord(描述进程的一个类)的一个实例以k-v的形式存了起来。Process.start调用了ActivityThread的main函数,这个函数主要作用是让当前线程变为Looper线程,当前线程也就是我们常说的UI线程或者主线程。
public static void main(String[] args){
.....
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
...
Looper.loop();
}
这里面还有一行重要的代码就是
thread.attach(false)l
我们看下这个attach方法
private void attach(boolean system) {
...
if (!system) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} else {
...
}
}
如果你熟悉Binder机制的话,应该知道这里的mgr应该是ActivityManagerProxy(AMP)的一个实例。调用了mgr的attachApplicationd方法并把成员变量mAppThread当作参数传递了过去。我们看下mAppThread的定义
final ApplicationThread mAppThread = new ApplicationThread();
ApplicationThread 是ActivityThread的内部类,继承自ApplicationThreadNative,是个Binder对象。
调用mgr的attachApplication的方法实际上最终是调用AMS的attachApplication方法,我们看下这个方法在AMS中的定义。
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
...
case ATTACH_APPLICATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IApplicationThread app = ApplicationThreadNative.asInterface(
data.readStrongBinder());
if (app != null) {
attachApplication(app);
}
reply.writeNoException();
return true;
}
...
}
//onTransact 是ActivityMangrerNative中定义的,AMS是AMN的子类,我们看到 case ATTACH_APPLICATION_TRANSACTION: 这种情况下调用了attachApplicationf方法
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
...
}
}
private final attachApplicationLocked(IApplicationThread thread,int pid){
...
thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
app.instrumentationUiAutomationConnection, testMode,
mBinderTransactionTrackingEnabled, enableTrackAllocation,
isRestrictedBackupMode || !normalMode, app.persistent,
new Configuration(mConfiguration), app.compat,
getCommonServicesLocked(app.isolated),
mCoreSettingsObserver.getCoreSettingsLocked());
...
}
AMS经过一系列处理,又通过RPC调用了ApplicationThread的bindApplication方法,我们看下这个方法的定义。
public final void bindApplication(String processName, ApplicationInfo appInfo,
...
AppBindData data = new AppBindData();
...
sendMessage(H.BIND_APPLICATION, data);
}
ApplicationThread组织参数后又丢给ActivityThread去处理,当ActivityThread收到这样一条消息时的处理方式如下
...
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
...
我们看下 handleBindApplication(data)方法
private void handleBindApplication(AppBindData data) {
...
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
...
Application app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
...
mInstrumentation.callApplicationOnCreate(app);
}
data.info是个LoadedApk的实例,LoadedApk描述的是我们的apk文件。LoadApk调用newInstance方法创建了一个Application对象,然后通过
mInstrumentation.callApplicationOnCreate(app);
代码调用了Application对象的onCreate方法。