Activity的启动流程(1)

一直在使用Activity,今天开始就来看下这个Activity究竟是如何启动的。
Activity分为根Activity和应用内Activity,根Activity就是我们点击手机屏幕上的icon时启动的Activity,应用内Activity就是我们应用内部跳转的Activity。今天我们从根Activity开始分析它的启动流程。
点击手机屏幕上的icon,其实就是android的Launcher接受点击事件,然后启动应用activity的过程,至于启动哪个Activity,这个在AndroidManifest.xml文件文件中进行配置:

<activity android:name="com.rock.MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>  

Launcher在启动应用的时候就会去启动<action android:name="android.intent.action.MAIN"/>并且<category android:name="android.intent.category.LAUNCHER"/>的Activity。可能会有疑问,Launcher怎么会有应用的这些信息呢?应用在安装完成之后,Launcher在界面上显示应用的icon,Launcher就会有应用对应的信息,具体可以去看下应用的安装过程。
Launcher继承Acitivity,故Launcher启动根Activity的时候调用startActivity(intent)会调用Activity的startActivity(intent),接下来就从Activity的startActivity(intent)开始逐步分析Activity的启动流程。由于整个流程比较长,故启动流程会多分几个篇。

1. Activity.startActivity(intent)

这个很好理解了,就是构造intent参数,然后调用startActivity函数了

public void startActivity(Intent intent) {
    startActivityForResult(intent, -1);
}

可以看到,startActivity(intent)接下来会调用startActivityForResult(intent, -1),requestCode为-1说明不需要获取启动Activity的结果。

2. startActivityForResult(intent, -1)

public void startActivityForResult(Intent intent, int requestCode) {
    if (mParent == null) {
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                ar.getResultData());
        }
        if (requestCode >= 0) {
            mStartedActivity = true;
        }
    } else {
        mParent.startActivityFromChild(this, intent, requestCode);
    }
}

mParent为空,故会执行mInstrumentation.execStartActivity这个函数。暂时不用纠结mInstrumentation,只需要知道Instrumentation是用来监控应用和系统的交互即可,接下来,Activity的启动会进入Instrumentation中。

3. Instrumentation.execStartActivity

执行到这个函数,参数突然多起来,看下它的函数原型:

public ActivityResult execStartActivity(Context who, IBinder 
   contextThread, IBinder token, Activity target, Intent intent, int questCode) 
    {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    ......
    try {
        intent.setAllowFds(false);
        int result = ActivityManagerNative.getDefault()
            .startActivity(whoThread, intent,
                    intent.resolveTypeIfNeeded(who.getContentResolver()),
                    null, 0, token, target != null ? target.mEmbeddedID : null,
                    requestCode, false, false, null, null, false);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
    }
    return null;
}

一下子感觉参数多了起来,没关系,一个一个参数分析。who是调用这个函数的Activity的Context;contextThread是应用和ActivityManangerService的桥梁,负责引用与ActivityManagerService之间的通信;token是调用这个函数的Activity的标识;tartget就是调用这个函数的Activity的实例;intent就是我们启动时传递的intent;requestCode就是调用startActivityForResult时传递的requestCode,从前面的分析可知,此处的requestCode为-1。接下来要进入ActivityManagerNative.getDefault() .startActivity这个函数了。看下ActivityManagerNative.getDefault()这个函数:

#1
static public IActivityManager getDefault() {
    return gDefault.get();
}
#2
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
    protected IActivityManager create() {
        IBinder b = ServiceManager.getService("activity");
        if (false) {
            Log.v("ActivityManager", "default service binder = " + b);
        }
        IActivityManager am = asInterface(b);
        if (false) {
            Log.v("ActivityManager", "default service = " + am);
        }
        return am;
    }
};
#3
static public IActivityManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }
    IActivityManager in =
        (IActivityManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }

    return new ActivityManagerProxy(obj);
}

代码片段#2表明gDefault是ActivityManagerService的一个单例,通过调用gDefault.get()获取的是ActivityManagerService的代理对象ActivityManagerProxy,也就是说ActivityManagerNative.getDefault().startActivity最终startActivity的调用是在ActivityManangerProxy中代理完成。这里涉及到Android的binder通信机制,后面再具体分析,反正记得这里面涉及到binder通信,最终startAcivity实在ActivityManangerService中完成的。ok,说了这么多,ActivityManagerProxy究竟有没有这个函数呢?

4. ActivityManagerProxy.startActivity

public int startActivity(IApplicationThread caller, Intent intent,
        String resolvedType, Uri[] grantedUriPermissions, int grantedMode,
        IBinder resultTo, String resultWho,
        int requestCode, boolean onlyIfNeeded,
        boolean debug, String profileFile, ParcelFileDescriptor profileFd,
        boolean autoStopProfiler) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IActivityManager.descriptor);
    data.writeStrongBinder(caller != null ? caller.asBinder() : null);
    intent.writeToParcel(data, 0);
    data.writeString(resolvedType);
    data.writeTypedArray(grantedUriPermissions, 0);
    data.writeInt(grantedMode);
    data.writeStrongBinder(resultTo);
    data.writeString(resultWho);
    data.writeInt(requestCode);
    data.writeInt(onlyIfNeeded ? 1 : 0);
    data.writeInt(debug ? 1 : 0);
    data.writeString(profileFile);
    if (profileFd != null) {
        data.writeInt(1);
        profileFd.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
    } else {
        data.writeInt(0);
    }
    data.writeInt(autoStopProfiler ? 1 : 0);
    mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
    reply.readException();
    int result = reply.readInt();
    reply.recycle();
    data.recycle();
    return result;
}

不要被这么多的参数吓到,仔细分析下,参数很好理解。caller就是负责应用和ActivityManangerService进行交互的ApplicationThread;intent就是我们传递的intent;resolveType为mime类型,在这里为null;grantedUriPermissions通过分析可知道在这里为null;grandMode在这里为0;resultTo标识启动这个Activity的Activity;resultWho表示应用的包名;后续的几个参数,boolean类型的均为false,非原始类型的数据均为null。
将这些数据全部写入Parcel类型data对象后,调用mRemote.transact函数进行跨进程通信,使ActivityManangerService执行startActivity的操作。下一节将会分析这一具体的流程。

猜你喜欢

转载自blog.csdn.net/rockstore/article/details/79588579