Android四大组件与进程启动关系总结
进程创建方法
四大组件(Activity、Service、ContentProvider、Broadcast)在所属进程没有启动的情况下,在调用startActivity、startService、ContentResolver.query、processNextBroadcast方法后经过层层调用最终会调用到ActivityManagerService中的startProcessLocked方法。
进程创建时机
进程的创建时机分为以下两种情况
1.单进程应用
首先会为app创建进程,然后执行具体操作(启动一个Activity等)。如果app进程已创建则会在该进程执行具体操作。
2.多进程应用
在这种情况下,会为每个配置过android:process属性的组件创建进程,如果再起启动该组件,不会为其创建进程。启动其他未配置process属性的组件,还是会先判断对应进程是否存在,不存在的话为此app创建进程。
详细流程
1.ActivityManagerService中的startProcessLocked方法中最终会调用Process.start()方法,此方法通过socket通信让Zygote进程为app创建一个新的进程,然后经过一系列调用最终会执行到ActivityThread.main方法
2.在ActivityThread.main方法中,会为主线程创建Looper对象并且执行loop方法,也会创建一个ActivityThread对象并且执行thread.attach方法。
public static void main(String[] args) {
...
//为主线程创建looper对象
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
//执行attach方法
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
}
if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
}
// End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
//执行轮询
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
3.ActivityThread.attach方法中会调用AMP的attachApplication的方法(AMP-ActivityManagerProxy,app进程与system_server进程利用Binder进行跨进程通讯的client,system_server中的ActivityManagerService为对应的Server)关键代码如下
private void attach(boolean system) {
...
//创建ActivityManagerProxy对象,ActivityManagerProxy
是ActivityManagerNative的内部类并且实现了IActivityManager接口
final IActivityManager mgr = ActivityManagerNative.getDefault();
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
}
...
}
其中mAppThread为ApplicationThread,ActivityThread的私有变量
//ApplicationThread实现了IApplicationThread接口
ApplicationThread mAppThread = new ApplicationThread();
ApplicationThread是与ActivityMangerService进行利用Binder进行跨进程通讯的Server,对应的ActivityMangerService中也有与之对应的client–ApplicationThreadProxy
4.接下来是调用AMP.attachApplication方法
public void attachApplication(IApplicationThread app) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeStrongBinder(app.asBinder());
mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
reply.recycle();
}
mRemote是ActivityMangerService转为的IBinder对象。mRemote调用transact方法进程跨进程通讯
5.下一步在AMN(AMN-ActivityManagerNative,ActivityMangerService继承AMN)中中执行
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
...
case ATTACH_APPLICATION_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
//app为ApplicationThreadProxy
IApplicationThread app =
ApplicationThreadNative.asInterface(data.readStrongBinder());
if (app != null) {
//将调用AMS的attachApplication方法,AMS继承了AMN
attachApplication(app);
}
reply.writeNoException();
return true;
}
}
}
上一步传进来的是ApplicationThread对象,通过ApplicationThreadNative.asInterface( data.readStrongBinder())方法获取其对应的ATP,代码如下
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread {
...
static public IApplicationThread asInterface(IBinder obj) {
if (obj == null) {
return null;
}
IApplicationThread in =
(IApplicationThread)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
return new ApplicationThreadProxy(obj);
}
...
}
6.AMS的attachApplication方法代码如下
//thread为ApplicationThreadProxy
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
7.attachApplicationLocked中会完成AMS与app进程的绑定关键代码如下
private final boolean attachApplicationLocked(IApplicationThread thread,
int pid) {
...
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());
...
}
下一步将调用ApplicationThreadProxy的bindApplication方法
8.ApplicationThreadProxy通过bindApplication方法经过Binder跨进程通讯最终调用的ApplicationThreadNative的onTransact的方法中
//第5步中,通过asInterface获取ApplicationThreadProxy时会将对应的ApplicaitonThread传入,
mRemote即为ApplicaitonThread的IBinder形式
mRemote.transact(BIND_APPLICATION_TRANSACTION, data, null,IBinder.FLAG_ONEWAY);
9.经过上一步,终于回到了app进程中ATN的onTransact方法
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
switch (code) {
...
case BIND_APPLICATION_TRANSACTION:
{
...
//将会调用ApplicaitonThread的bindApplication方法,ApplicaitonThread继承
ApplicationThreadNative(ATN)
bindApplication(packageName, info, providers, testName, profilerInfo
, testArgs,testWatcher, uiAutomationConnection
, testMode, openGlTrace,restrictedBackupMode
, persistent, config, compatInfo, services, coreSettings);
return true;
}
..
}
10.ApplicationThread最终会使用ActivityThread中的H(handler)调用到ActivityThread中的handleBindApplication方法完成一系列初始化。至此进程启动完毕
总结
通过4大组件启动进程时,首先会完成app进程的创建,app进程创建完毕后会完成app进程与system_server中的ActivityManagerService的相互绑定(AMP.attachApplication、ATP.bindApplication)。这两个方法是通过Binder完成跨进程通讯。
因为ActivityMangerService管理所有app的生命周期,所以使用了代理模式,每个app绑定AMS时都是用的是AMS对应的代理类AMP,而AMP中的mRemote对应的都是AMS。相同的道理在AMS管理app时使用的是ATP,而ATP中的mRemote则是ATP对应的AT。ATP与AMP是Binder的client端,AMS与AT是对应的Sever。