Android四大组件与进程启动关系总结

来源:互联网 发布:机械力学分析软件 编辑:程序博客网 时间:2024/06/05 01:08

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.在Activity.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为ApplicationThreadProxypublic 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。

参考链接:
http://gityuan.com/2016/10/09/app-process-create-2/