Activity啟動(dòng)流程

好吧蓝牲,終于要開始講解Activity的啟動(dòng)流程了,Activity的啟動(dòng)流程相對(duì)復(fù)雜一下兵迅,涉及到了Activity中的生命周期方法抢韭,涉及到了Android體系的CS模式,涉及到了Android中進(jìn)程通訊Binder機(jī)制等等恍箭,

首先介紹一下Activity刻恭,這里引用一下Android guide中對(duì)Activity的介紹:

An activity represents a single screen with a user interface. For example, an email application might have one activity that shows a list of new emails, another activity to compose an email, and another activity for reading emails. Although the activities work together to form a cohesive user experience in the email application, each one is independent of the others. As such, a different application can start any one of these activities (if the email application allows it). For example, a camera application can start the activity in the email application that composes new mail, in order for the user to share a picture.

這里介紹的Activity的大概意思就是說,activity在Android系統(tǒng)中代表的就是一個(gè)屏幕扯夭,一個(gè)App就是由許多個(gè)不同的Acitivty組成的吠各,并且不同進(jìn)程之間的Activity是可以相互調(diào)用的臀突。

在介紹Activity的啟動(dòng)流程之前,我們先介紹幾個(gè)概念:

  • Activity的生命周期

protected void onCreate(Bundle savedInstanceState);
protected void onRestart();
protected void onStart();
protected void onResume();
protected void onPause();
protected void onStop();
protected void onDestory();

以上為Activity生命周期中的各個(gè)時(shí)期的回調(diào)方法贾漏,在不同的方法中我們可以執(zhí)行不同的邏輯候学。
關(guān)于Activity生命周期的詳細(xì)介紹可以參考:
Android activity的生命周期

  • Activity的啟動(dòng)模式

activity啟動(dòng)時(shí)可以設(shè)置不同的啟動(dòng)模式,主要是:standrand纵散,singleTop梳码,singleTask,instance等四種啟動(dòng)模式伍掀,不同的啟動(dòng)模式在啟動(dòng)Activity時(shí)會(huì)執(zhí)行不同的邏輯掰茶,系統(tǒng)會(huì)按不同的啟動(dòng)模式將Activity存放到不同的activity棧中。
關(guān)于Activity啟動(dòng)模式的詳細(xì)介紹蜜笤,可以參考:Android任務(wù)和返回棧完全解析

  • Activity的啟動(dòng)進(jìn)程

在Manifest.xml中定義Activity的時(shí)候濒蒋,Activity默認(rèn)是屬于進(jìn)程名稱為包名的進(jìn)程的,當(dāng)然這時(shí)候是可以指定Activity的啟動(dòng)進(jìn)程把兔,所以在Activity啟動(dòng)時(shí)首先會(huì)檢測(cè)當(dāng)前Activity所屬的進(jìn)程是否已經(jīng)啟動(dòng)沪伙,若進(jìn)程沒有啟動(dòng)鸵赖,則首先會(huì)啟動(dòng)該進(jìn)程燎字,并在該進(jìn)程啟動(dòng)之后才會(huì)執(zhí)行Activity的啟動(dòng)過程狼讨。

  • Intent啟動(dòng)Activity的方式

Intent啟動(dòng)Activity分為兩種乒躺,顯示啟動(dòng)和隱士啟動(dòng)轮洋,顯示啟動(dòng)就是在初始化Intent對(duì)象的時(shí)候直接引用需要啟動(dòng)的Activity的字節(jié)碼效览,顯示引用的好處就是可以直接告訴Intent對(duì)象啟動(dòng)的Activity對(duì)象不需要執(zhí)行intent filter索引需要啟動(dòng)哪一個(gè)Activity残拐,但是顯示引用不能啟動(dòng)其他進(jìn)程的Activity對(duì)象愧杯,因?yàn)闊o法獲取其他進(jìn)程的Activity對(duì)象的字節(jié)碼晾咪,而隱式啟動(dòng)則可以通過配置Intent Filter啟動(dòng)其他進(jìn)程的Activity對(duì)象收擦,因此在應(yīng)用內(nèi),我們一般都是使用顯示啟動(dòng)的方式啟動(dòng)Activity谍倦,而如果需要啟動(dòng)其他應(yīng)用的Activity時(shí)塞赂,一般使用隱式啟動(dòng)的方式。

  • Android Framework層的CS模式
    通過前幾篇文章的介紹我們知道android系統(tǒng)在啟動(dòng)過程中會(huì)執(zhí)行這樣的邏輯:
    Zygote進(jìn)程 --> SystemServer進(jìn)程 --> 各種系統(tǒng)服務(wù) --> 應(yīng)用進(jìn)程
    在Actvity啟動(dòng)過程中剂跟,其實(shí)是應(yīng)用進(jìn)程與SystemServer進(jìn)程相互配合啟動(dòng)Activity的過程减途,其中應(yīng)用進(jìn)程主要用于執(zhí)行具體的Activity的啟動(dòng)過程,回調(diào)生命周期方法等操作曹洽,而SystemServer進(jìn)程則主要是調(diào)用其中的各種服務(wù)鳍置,將Activity保存在棧中,協(xié)調(diào)各種系統(tǒng)資源等操作送淆。

  • Android系統(tǒng)進(jìn)程間通訊Binder機(jī)制
    Android系統(tǒng)存了Zygote進(jìn)程和SystemServer進(jìn)程以及各種應(yīng)用進(jìn)程等税产,為了能夠?qū)崿F(xiàn)各種進(jìn)程之間的通訊,Android系統(tǒng)采用了自己的進(jìn)程間通訊方式Binder機(jī)制。其中主要涉及到了四種角色:Binder Client辟拷,Binder Server撞羽,Binder Manager, Binder driver衫冻。各種角色之間的關(guān)系可以參考下面這張圖的介紹:


    這里寫圖片描述

好吧诀紊,前面我們介紹了一些Activity啟動(dòng)過程中需要的相關(guān)知識(shí)點(diǎn),下面我們開始Activity啟動(dòng)流程的講解隅俘。邻奠。。为居。

還記得前面我們講過的Launcher啟動(dòng)流程么碌宴?可以參考:android源碼解析之(十)-->Launcher啟動(dòng)流程
在這篇文章中我們說Launcher啟動(dòng)之后會(huì)將各個(gè)應(yīng)用包名和icon與app name保存起來,然后執(zhí)行icon的點(diǎn)擊事件的時(shí)候調(diào)用startActivity方法:

@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Intent intent = intentForPosition(position);
        startActivity(intent);
    }

protected Intent intentForPosition(int position) {
        ActivityAdapter adapter = (ActivityAdapter) mAdapter;
        return adapter.intentForPosition(position);
    }

public Intent intentForPosition(int position) {
            if (mActivitiesList == null) {
                return null;
            }

            Intent intent = new Intent(mIntent);
            ListItem item = mActivitiesList.get(position);
            intent.setClassName(item.packageName, item.className);
            if (item.extras != null) {
                intent.putExtras(item.extras);
            }
            return intent;
        }

可以發(fā)現(xiàn)蒙畴,我們?cè)趩?dòng)Activity的時(shí)候贰镣,執(zhí)行的邏輯就是創(chuàng)建一個(gè)Intent對(duì)象,然后初始化Intent對(duì)象膳凝,使用隱式啟動(dòng)的方式啟動(dòng)該Acvitity碑隆,這里為什么不能使用顯示啟動(dòng)的方式呢?

這是因?yàn)長(zhǎng)auncher程序啟動(dòng)的Activity一般都是啟動(dòng)一個(gè)新的應(yīng)用進(jìn)程鸠项,該進(jìn)程與Launcher進(jìn)程不是在同一個(gè)進(jìn)程中干跛,所以也就無法引用到啟動(dòng)的Activity字節(jié)碼子姜,自然也就無法啟動(dòng)該Activity了祟绊。

繼續(xù),我們查看startActivity方法的具體實(shí)現(xiàn):

</br><strong><font size="6" >一:開始請(qǐng)求執(zhí)行啟動(dòng)Activity</font><strong>

<font color="red">
MyActivity.startActivity()
Activity.startActivity()
Activity.startActivityForResult
Instrumentation.execStartActivty
ActivityManagerNative.getDefault().startActivityAsUser()
</font>

在我們的Activity中調(diào)用startActivity方法哥捕,會(huì)執(zhí)行Activity中的startActivity

@Override
    public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

然后在Activity中的startActivity方法體里調(diào)用了startActivity的重載方法牧抽,這里我們看一下其重載方法的實(shí)現(xiàn):

@Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

由于在上一步驟中我們傳遞的Bunde對(duì)象為空,所以這里我們執(zhí)行的是else分支的邏輯遥赚,所以這里調(diào)用了startActivityForResult方法扬舒,并且傳遞的參數(shù)為intent和-1.

<font color="#A52A2A">注意:通過這里的代碼我們可以發(fā)現(xiàn),其實(shí)我們?cè)贏ctivity中調(diào)用startActivity的內(nèi)部也是調(diào)用的startActivityForResult的凫佛。那么為什么調(diào)用startActivityForResult可以在Activity中回調(diào)onActivityResult而調(diào)用startActivity則不可以呢讲坎?可以發(fā)現(xiàn)其主要的區(qū)別是調(diào)用startActivity內(nèi)部調(diào)用startActivityForResult傳遞的傳輸requestCode值為-1,也就是說我們?cè)贏ctivity調(diào)用startActivityForResult的時(shí)候傳遞的requestCode值為-1的話愧薛,那么onActivityResult是不起作用的晨炕。
實(shí)際上,經(jīng)測(cè)試requestCode的值小于0的時(shí)候都是不起作用的毫炉,所以當(dāng)我們調(diào)用startActivityForResult的時(shí)候需要注意這一點(diǎn)瓮栗。</font>

好吧,我們繼續(xù)往下看,startActivityForResult方法的具體實(shí)現(xiàn):

public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            if (requestCode >= 0) {
                // If this start is requesting a result, we can avoid making
                // the activity visible until the result is received.  Setting
                // this code during onCreate(Bundle savedInstanceState) or onResume() will keep the
                // activity hidden during this time, to avoid flickering.
                // This can only be done when a result is requested because
                // that guarantees we will get information back when the
                // activity is finished, no matter what happens to it.
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
            if (options != null) {
                mParent.startActivityFromChild(this, intent, requestCode, options);
            } else {
                // Note we want to go through this method for compatibility with
                // existing applications that may have overridden it.
                mParent.startActivityFromChild(this, intent, requestCode);
            }
        }
    }

可以發(fā)現(xiàn)由于我們是第一次啟動(dòng)Activity费奸,所以這里的mParent為空弥激,所以會(huì)執(zhí)行if分之,然后調(diào)用mInstrumentation.execStartActivity方法愿阐,并且這里需要注意的是微服,有一個(gè)判斷邏輯:

if (requestCode >= 0) {
    mStartedActivity = true;
}

通過注釋也驗(yàn)證了我們剛剛的說法即,調(diào)用startActivityForResult的時(shí)候只有requestCode的值大于等于0缨历,onActivityResult才會(huì)被回調(diào)职辨。

然后我們看一下mInstrumentation.execStartActivity方法的實(shí)現(xiàn)。在查看execStartActivity方法之前戈二,我們需要對(duì)mInstrumentation對(duì)象有一個(gè)了解舒裤?什么是Instrumentation?Instrumentation是android系統(tǒng)中啟動(dòng)Activity的一個(gè)實(shí)際操作類觉吭,也就是說Activity在應(yīng)用進(jìn)程端的啟動(dòng)實(shí)際上就是Instrumentation執(zhí)行的腾供,那么為什么說是在應(yīng)用進(jìn)程端的啟動(dòng)呢?實(shí)際上acitivty的啟動(dòng)分為應(yīng)用進(jìn)程端的啟動(dòng)和SystemServer服務(wù)進(jìn)程端的啟動(dòng)的鲜滩,多個(gè)應(yīng)用進(jìn)程相互配合最終完成了Activity在系統(tǒng)中的啟動(dòng)的伴鳖,而在應(yīng)用進(jìn)程端的啟動(dòng)實(shí)際的操作類就是Intrumentation來執(zhí)行的,可能還是有點(diǎn)繞口徙硅,沒關(guān)系榜聂,隨著我們慢慢的解析大家就會(huì)對(duì)Instrumentation的認(rèn)識(shí)逐漸加深的。

可以發(fā)現(xiàn)execStartActivity方法傳遞的幾個(gè)參數(shù):
this嗓蘑,為啟動(dòng)Activity的對(duì)象须肆;
contextThread,為Binder對(duì)象桩皿,是主進(jìn)程的context對(duì)象豌汇;
token,也是一個(gè)Binder對(duì)象泄隔,指向了服務(wù)端一個(gè)ActivityRecord對(duì)象拒贱;
target,為啟動(dòng)的Activity佛嬉;
intent逻澳,啟動(dòng)的Intent對(duì)象;
requestCode暖呕,請(qǐng)求碼斜做;
options,參數(shù)缰揪;

這樣就調(diào)用了Imstrument.execStartActivity方法了:

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
        return null;
    }

我們發(fā)現(xiàn)在這個(gè)方法中主要調(diào)用ActivityManagerNative.getDefault().startActivity方法陨享,那么ActivityManagerNative又是個(gè)什么鬼呢葱淳?查看一下getDefault()對(duì)象的實(shí)現(xiàn):

static public IActivityManager getDefault() {
        return gDefault.get();
    }

好吧,相當(dāng)之簡(jiǎn)單直接返回的是gDefault.get()抛姑,那么gDefault又是什么呢赞厕?

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;
        }
    };

可以發(fā)現(xiàn)啟動(dòng)過asInterface()方法創(chuàng)建,然后我們繼續(xù)看一下asInterface方法的實(shí)現(xiàn):

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);
    }

好吧定硝,最后直接返回一個(gè)ActivityManagerProxy對(duì)象皿桑,而ActivityManagerProxy繼承與IActivityManager,到了這里就引出了我們android系統(tǒng)中很重要的一個(gè)概念:Binder機(jī)制蔬啡。我們知道應(yīng)用進(jìn)程與SystemServer進(jìn)程屬于兩個(gè)不同的進(jìn)程诲侮,進(jìn)程之間需要通訊,android系統(tǒng)采取了自身設(shè)計(jì)的Binder機(jī)制箱蟆,這里的ActivityManagerProxy和ActivityManagerNative都是繼承與IActivityManager的而SystemServer進(jìn)程中的ActivityManagerService對(duì)象則繼承與ActivityManagerNative沟绪。簡(jiǎn)單的表示:
Binder接口 --> ActivityManagerNative/ActivityManagerProxy --> ActivityManagerService;

這樣空猜,ActivityManagerNative與ActivityManagerProxy相當(dāng)于一個(gè)Binder的客戶端而ActivityManagerService相當(dāng)于Binder的服務(wù)端绽慈,這樣當(dāng)ActivityManagerNative調(diào)用接口方法的時(shí)候底層通過Binder driver就會(huì)將請(qǐng)求數(shù)據(jù)與請(qǐng)求傳遞給server端,并在server端執(zhí)行具體的接口邏輯辈毯。需要注意的是Binder機(jī)制是單向的坝疼,是異步的,也就是說只能通過client端向server端傳遞數(shù)據(jù)與請(qǐng)求而不同等待服務(wù)端的返回谆沃,也無法返回钝凶,那如果SystemServer進(jìn)程想向應(yīng)用進(jìn)程傳遞數(shù)據(jù)怎么辦?這時(shí)候就需要重新定義一個(gè)Binder請(qǐng)求以SystemServer為client端唁影,以應(yīng)用進(jìn)程為server端耕陷,這樣就是實(shí)現(xiàn)了兩個(gè)進(jìn)程之間的雙向通訊。

好了夭咬,說了這么多我們知道這里的ActivityManagerNative是ActivityManagerService在應(yīng)用進(jìn)程的一個(gè)client就好了啃炸,通過它就可以滴啊用ActivityManagerService的方法了铆隘。

繼續(xù)往下卡卓舵,我們調(diào)用的是:

int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);

這里通過我們剛剛的分析,ActivityManagerNative.getDefault()方法會(huì)返回一個(gè)ActivityManagerProxy對(duì)象膀钠,那么我們看一下ActivityManagerProxy對(duì)象的startActivity方法:

public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
            String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(caller != null ? caller.asBinder() : null);
        data.writeString(callingPackage);
        intent.writeToParcel(data, 0);
        data.writeString(resolvedType);
        data.writeStrongBinder(resultTo);
        data.writeString(resultWho);
        data.writeInt(requestCode);
        data.writeInt(startFlags);
        if (profilerInfo != null) {
            data.writeInt(1);
            profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
        } else {
            data.writeInt(0);
        }
        if (options != null) {
            data.writeInt(1);
            options.writeToParcel(data, 0);
        } else {
            data.writeInt(0);
        }
        mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
        reply.readException();
        int result = reply.readInt();
        reply.recycle();
        data.recycle();
        return result;
    }

這里就涉及到了具體的Binder數(shù)據(jù)傳輸機(jī)制了掏湾,我們不做過多的分析,知道通過數(shù)據(jù)傳輸之后就會(huì)調(diào)用SystemServer進(jìn)程的ActivityManagerService的startActivity就好了肿嘲。

以上其實(shí)都是發(fā)生在應(yīng)用進(jìn)程中融击,下面開始調(diào)用的ActivityManagerService的執(zhí)行時(shí)發(fā)生在SystemServer進(jìn)程。


<strong><font size="6">二:ActivityManagerService接收啟動(dòng)Activity的請(qǐng)求</font></strong>

<font color="red">
ActivityManagerService.startActivity()
ActvityiManagerService.startActivityAsUser()
ActivityStackSupervisor.startActivityMayWait()
ActivityStackSupervisor.startActivityLocked()
ActivityStackSupervisor.startActivityUncheckedLocked()
ActivityStackSupervisor.startActivityLocked()
ActivityStackSupervisor.resumeTopActivitiesLocked()
ActivityStackSupervisor.resumeTopActivityInnerLocked()
</font>

好吧雳窟,代碼量比較大尊浪,慢慢看匣屡,首先看一下ActivityManagerService.startActivity的具體實(shí)現(xiàn);

@Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            UserHandle.getCallingUserId());
    }

可以看到拇涤,該方法并沒有實(shí)現(xiàn)什么邏輯捣作,直接調(diào)用了startActivityAsUser方法,我們繼續(xù)看一下startActivityAsUser方法的實(shí)現(xiàn):

@Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, options, false, userId, null, null);
    }

可以看到這里只是進(jìn)行了一些關(guān)于userid的邏輯判斷鹅士,然后就調(diào)用mStackSupervisor.startActivityMayWait方法券躁,下面我們來看一下這個(gè)方法的具體實(shí)現(xiàn):

final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
            Bundle options, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask) {
            ...

            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage,
                    realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                    componentSpecified, null, container, inTask);
            ...
            return res;
    }

這個(gè)方法中執(zhí)行了啟動(dòng)Activity的一些其他邏輯判斷,在經(jīng)過判斷邏輯之后調(diào)用startActivityLocked方法:

final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, ActivityInfo aInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode,
            int callingPid, int callingUid, String callingPackage,
            int realCallingPid, int realCallingUid, int startFlags, Bundle options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            ActivityContainer container, TaskRecord inTask) {
        int err = ActivityManager.START_SUCCESS;

        ...
        err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, true, options, inTask);

        ...
        return err;
    }

這個(gè)方法中主要構(gòu)造了ActivityManagerService端的Activity對(duì)象-->ActivityRecord掉盅,并根據(jù)Activity的啟動(dòng)模式執(zhí)行了相關(guān)邏輯也拜。然后調(diào)用了startActivityUncheckedLocked方法:

final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
            boolean doResume, Bundle options, TaskRecord inTask) {
        ...
        ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
        targetStack.mLastPausedActivity = null;
        targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
        if (!launchTaskBehind) {
            // Don't set focus on an activity that's going to the back.
            mService.setFocusedActivityLocked(r, "startedActivity");
        }
        return ActivityManager.START_SUCCESS;
    }

startActivityUncheckedLocked方法中只要執(zhí)行了不同啟動(dòng)模式不同棧的處理宣旱,并最后調(diào)用了startActivityLocked的重載方法:

final void startActivityLocked(ActivityRecord r, boolean newTask,
            boolean doResume, boolean keepCurTransition, Bundle options) {
        ...
        if (doResume) {
            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
        }
    }

這個(gè)startActivityLocked方法主要執(zhí)行初始化了windowManager服務(wù)蔓纠,然后調(diào)用resumeTopActivitiesLocked方法:

boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
            Bundle targetOptions) {
        if (targetStack == null) {
            targetStack = mFocusedStack;
        }
        // Do targetStack first.
        boolean result = false;
        if (isFrontStack(targetStack)) {
            result = targetStack.resumeTopActivityLocked(target, targetOptions);
        }

        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (stack == targetStack) {
                    // Already started above.
                    continue;
                }
                if (isFrontStack(stack)) {
                    stack.resumeTopActivityLocked(null);
                }
            }
        }
        return result;
    }

可以發(fā)現(xiàn)經(jīng)過循環(huán)邏輯判斷之后,最終調(diào)用了resumeTopActivityLocked方法:

final boolean resumeTopActivityLocked(ActivityRecord prev) {
        return resumeTopActivityLocked(prev, null);
    }

然后調(diào)用:

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

繼續(xù)調(diào)用resumeTopActivityInnerLocked方法:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {

        ...
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "resumeTopActivityLocked: Pausing " + mResumedActivity);
            pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
        }        ...
        return true;
    }

經(jīng)過一系列處理邏輯之后最終調(diào)用了startPausingLocked方法观游,這個(gè)方法作用就是讓系統(tǒng)中棧中的Activity執(zhí)行onPause方法永票。


<strong><font size="6">三:執(zhí)行棧頂Activity的onPause方法

<font color="red">
ActivityStack.startPausingLocked()
IApplicationThread.schudulePauseActivity()
ActivityThread.sendMessage()
ActivityThread.H.sendMessage();
ActivityThread.H.handleMessage()
ActivityThread.handlePauseActivity()
ActivityThread.performPauseActivity()
Activity.performPause()
Activity.onPause()
ActivityManagerNative.getDefault().activityPaused(token)
ActivityManagerService.activityPaused()
ActivityStack.activityPausedLocked()
ActivityStack.completePauseLocked()
ActivityStack.resumeTopActivitiesLocked()
ActivityStack.resumeTopActivityLocked()
ActivityStack.resumeTopActivityInnerLocked()
ActivityStack.startSpecificActivityLocked
</font>

好吧岸军,方法比較多也比較亂,首先來看startPausingLocked方法:

final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
            boolean dontWait) {
        ...
        if (prev.app != null && prev.app.thread != null) {
            if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
            try {
                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                        prev.userId, System.identityHashCode(prev),
                        prev.shortComponentName);
                mService.updateUsageStats(prev, false);
                prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
                        userLeaving, prev.configChangeFlags, dontWait);
            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivity = null;
                mLastPausedActivity = null;
                mLastNoHistoryActivity = null;
            }
        } else {
            mPausingActivity = null;
            mLastPausedActivity = null;
            mLastNoHistoryActivity = null;
        }
        ...
    }

可以看到這里執(zhí)行了pre.app.thread.schedulePauseActivity方法瓦侮,通過分析不難發(fā)現(xiàn)這里的thread是一個(gè)IApplicationThread類型的對(duì)象艰赞,而在ActivityThread中也定義了一個(gè)ApplicationThread的類,其繼承了IApplicationThread肚吏,并且都是Binder對(duì)象方妖,不難看出這里的IAppcation是一個(gè)Binder的client端而ActivityThread中的ApplicationThread是一個(gè)Binder對(duì)象的server端,所以通過這里的thread.schedulePauseActivity實(shí)際上調(diào)用的就是ApplicationThread的schedulePauseActivity方法罚攀。

<font color="red">這里的ApplicationThread可以和ActivityManagerNative對(duì)于一下:
通過ActivityManagerNative --> ActivityManagerService實(shí)現(xiàn)了應(yīng)用進(jìn)程與SystemServer進(jìn)程的通訊
通過AppicationThread <-- IApplicationThread實(shí)現(xiàn)了SystemServer進(jìn)程與應(yīng)用進(jìn)程的通訊</font>

然后我們繼續(xù)看一下ActivityThread中schedulePauseActivity的具體實(shí)現(xiàn):

public final void schedulePauseActivity(IBinder token, boolean finished,
                boolean userLeaving, int configChanges, boolean dontReport) {
            sendMessage(
                    finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
                    token,
                    (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
                    configChanges);
        }

發(fā)送了PAUSE_ACTIVITY_FINISHING消息党觅,然后看一下sendMessage的實(shí)現(xiàn)方法:

private void sendMessage(int what, Object obj, int arg1, int arg2) {
        sendMessage(what, obj, arg1, arg2, false);
    }

調(diào)用了其重載方法:

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        if (DEBUG_MESSAGES) Slog.v(
            TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
            + ": " + arg1 + " / " + obj);
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

最終調(diào)用了mH的sendMessage方法,mH是在ActivityThread中定義的一個(gè)Handler對(duì)象斋泄,主要處理SystemServer進(jìn)程的消息杯瞻,我們看一下其handleMessge方法的實(shí)現(xiàn):

public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
                ...
                case PAUSE_ACTIVITY_FINISHING:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
                    handlePauseActivity((IBinder)msg.obj, true, (msg.arg1&1) != 0, msg.arg2,
                            (msg.arg1&1) != 0);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
                ...
}

可以發(fā)現(xiàn)其調(diào)用了handlePauseActivity方法:

private void handlePauseActivity(IBinder token, boolean finished,
            boolean userLeaving, int configChanges, boolean dontReport) {
        ActivityClientRecord r = mActivities.get(token);
        if (r != null) {
            //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
            if (userLeaving) {
                performUserLeavingActivity(r);
            }

            r.activity.mConfigChangeFlags |= configChanges;
            performPauseActivity(token, finished, r.isPreHoneycomb());

            // Make sure any pending writes are now committed.
            if (r.isPreHoneycomb()) {
                QueuedWork.waitToFinish();
            }

            // Tell the activity manager we have paused.
            if (!dontReport) {
                try {
                    ActivityManagerNative.getDefault().activityPaused(token);
                } catch (RemoteException ex) {
                }
            }
            mSomeActivitiesChanged = true;
        }
    }

然后在方法體內(nèi)部通過調(diào)用performPauseActivity方法來實(shí)現(xiàn)對(duì)棧頂Activity的onPause生命周期方法的回調(diào),可以具體看一下他的實(shí)現(xiàn):

final Bundle performPauseActivity(IBinder token, boolean finished,
            boolean saveState) {
        ActivityClientRecord r = mActivities.get(token);
        return r != null ? performPauseActivity(r, finished, saveState) : null;
    }

然后調(diào)用其重載方法:

final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
            boolean saveState) {
        ...
        mInstrumentation.callActivityOnPause(r.activity);
        ...

        return !r.activity.mFinished && saveState ? r.state : null;
    }

這樣回到了mInstrumentation的callActivityOnPuase方法:

public void callActivityOnPause(Activity activity) {
        activity.performPause();
    }

呵呵炫掐,原來最終回調(diào)到了Activity的performPause方法:

final void performPause() {
        mDoReportFullyDrawn = false;
        mFragments.dispatchPause();
        mCalled = false;
        onPause();
        mResumed = false;
        if (!mCalled && getApplicationInfo().targetSdkVersion
                >= android.os.Build.VERSION_CODES.GINGERBREAD) {
            throw new SuperNotCalledException(
                    "Activity " + mComponent.toShortString() +
                    " did not call through to super.onPause()");
        }
        mResumed = false;
    }

終于魁莉,太不容易了,回調(diào)到了Activity的onPause方法募胃,哈哈旗唁,Activity生命周期中的第一個(gè)生命周期方法終于被我們找到了。痹束。检疫。。也就是說我們?cè)趩?dòng)一個(gè)Activity的時(shí)候最先被執(zhí)行的是棧頂?shù)腁ctivity的onPause方法祷嘶。記住這點(diǎn)吧屎媳,面試的時(shí)候經(jīng)常會(huì)問到類似的問題夺溢。

然后回到我們的handlePauseActivity方法,在該方法的最后面執(zhí)行了ActivityManagerNative.getDefault().activityPaused(token);方法烛谊,這是應(yīng)用進(jìn)程告訴服務(wù)進(jìn)程企垦,棧頂Activity已經(jīng)執(zhí)行完成onPause方法了,通過前面我們的分析晒来,我們知道這句話最終會(huì)被ActivityManagerService的activityPaused方法執(zhí)行钞诡。

@Override
    public final void activityPaused(IBinder token) {
        final long origId = Binder.clearCallingIdentity();
        synchronized(this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                stack.activityPausedLocked(token, false);
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

可以發(fā)現(xiàn),該方法內(nèi)部會(huì)調(diào)用ActivityStack的activityPausedLocked方法湃崩,好吧荧降,繼續(xù)看一下activityPausedLocked方法的實(shí)現(xiàn):

final void activityPausedLocked(IBinder token, boolean timeout) {
            ...
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                        + (timeout ? " (due to timeout)" : " (pause complete)"));
                completePauseLocked(true);
            ...
    }

然后執(zhí)行了completePauseLocked方法:

private void completePauseLocked(boolean resumeNext) {
        ...

        if (resumeNext) {
            final ActivityStack topStack = mStackSupervisor.getFocusedStack();
            if (!mService.isSleepingOrShuttingDown()) {
                mStackSupervisor.resumeTopActivitiesLocked(topStack, prev, null);
            } else {
                mStackSupervisor.checkReadyForSleepLocked();
                ActivityRecord top = topStack.topRunningActivityLocked(null);
                if (top == null || (prev != null && top != prev)) {
                    // If there are no more activities available to run,
                    // do resume anyway to start something.  Also if the top
                    // activity on the stack is not the just paused activity,
                    // we need to go ahead and resume it to ensure we complete
                    // an in-flight app switch.
                    mStackSupervisor.resumeTopActivitiesLocked(topStack, null, null);
                }
            }
        }
        ...
    }

經(jīng)過了一系列的邏輯之后,又調(diào)用了resumeTopActivitiesLocked方法攒读,又回到了第二步中解析的方法中了朵诫,這樣經(jīng)過
resumeTopActivitiesLocked -->
ActivityStack.resumeTopActivityLocked() -->
resumeTopActivityInnerLocked -->
startSpecificActivityLocked
好吧,我們看一下startSpecificActivityLocked的具體實(shí)現(xiàn):

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.task.stack.setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
    }

可以發(fā)現(xiàn)在這個(gè)方法中薄扁,首先會(huì)判斷一下需要啟動(dòng)的Activity所需要的應(yīng)用進(jìn)程是否已經(jīng)啟動(dòng)剪返,若啟動(dòng)的話,則直接調(diào)用realStartAtivityLocked方法邓梅,否則調(diào)用startProcessLocked方法脱盲,用于啟動(dòng)應(yīng)用進(jìn)程。
這樣關(guān)于啟動(dòng)Activity時(shí)的第三步驟就已經(jīng)執(zhí)行完成了日缨,這里主要是實(shí)現(xiàn)了對(duì)棧頂Activity執(zhí)行onPause
方法钱反,而這個(gè)方法首先判斷需要啟動(dòng)的Activity所屬的進(jìn)程是否已經(jīng)啟動(dòng),若已經(jīng)啟動(dòng)則直接調(diào)用啟動(dòng)Activity的方法匣距,否則將先啟動(dòng)Activity的應(yīng)用進(jìn)程面哥,然后在啟動(dòng)該Activity。


<strong><font size="6">四:?jiǎn)?dòng)Activity所屬的應(yīng)用進(jìn)程</font></strong>

關(guān)于如何啟動(dòng)應(yīng)用進(jìn)程毅待,前面的一篇文章已經(jīng)做了介紹尚卫,可參考:<a > android源碼解析之(十一)-->應(yīng)用進(jìn)程啟動(dòng)流程</a> 這里在簡(jiǎn)單的介紹一下

<font color="red">
ActivityManagerService.startProcessLocked()
Process.start()
ActivityThread.main()
ActivityThread.attach()
ActivityManagerNative.getDefault().attachApplication()
ActivityManagerService.attachApplication()
</font>

好吧,首先看一下startProcessLocked()方法的具體實(shí)現(xiàn):

private final void startProcessLocked(ProcessRecord app,
            String hostingType, String hostingNameStr) {
        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
                null /* entryPoint */, null /* entryPointArgs */);
    }

然后回調(diào)了其重載的startProcessLocked方法:

private final void startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
            ...
            boolean isActivityProcess = (entryPoint == null);
            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
                    app.processName);
            checkTime(startTime, "startProcess: asking zygote to start proc");
            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);
            checkTime(startTime, "startProcess: returned from zygote!");
            ...
    }

可以發(fā)現(xiàn)其經(jīng)過一系列的初始化操作之后調(diào)用了Process.start方法尸红,并且傳入了啟動(dòng)的類名“android.app.ActivityThread”:

public static final ProcessStartResult start(final String processClass,
                                  final String niceName,
                                  int uid, int gid, int[] gids,
                                  int debugFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String[] zygoteArgs) {
        try {
            return startViaZygote(processClass, niceName, uid, gid, gids,
                    debugFlags, mountExternal, targetSdkVersion, seInfo,
                    abi, instructionSet, appDataDir, zygoteArgs);
        } catch (ZygoteStartFailedEx ex) {
            Log.e(LOG_TAG,
                    "Starting VM process through Zygote failed");
            throw new RuntimeException(
                    "Starting VM process through Zygote failed", ex);
        }
    }

然后調(diào)用了startViaZygote方法:

private static ProcessStartResult startViaZygote(final String processClass,
                                  final String niceName,
                                  final int uid, final int gid,
                                  final int[] gids,
                                  int debugFlags, int mountExternal,
                                  int targetSdkVersion,
                                  String seInfo,
                                  String abi,
                                  String instructionSet,
                                  String appDataDir,
                                  String[] extraArgs)
                                  throws ZygoteStartFailedEx {
        synchronized(Process.class) {
            ...

            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
        }
    }

繼續(xù)查看一下zygoteSendArgsAndGetResult方法的實(shí)現(xiàn):

private static ProcessStartResult zygoteSendArgsAndGetResult(
            ZygoteState zygoteState, ArrayList<String> args)
            throws ZygoteStartFailedEx {
        try {
            /**
             * See com.android.internal.os.ZygoteInit.readArgumentList()
             * Presently the wire format to the zygote process is:
             * a) a count of arguments (argc, in essence)
             * b) a number of newline-separated argument strings equal to count
             *
             * After the zygote process reads these it will write the pid of
             * the child or -1 on failure, followed by boolean to
             * indicate whether a wrapper process was used.
             */
            final BufferedWriter writer = zygoteState.writer;
            final DataInputStream inputStream = zygoteState.inputStream;

            writer.write(Integer.toString(args.size()));
            writer.newLine();

            int sz = args.size();
            for (int i = 0; i < sz; i++) {
                String arg = args.get(i);
                if (arg.indexOf('\n') >= 0) {
                    throw new ZygoteStartFailedEx(
                            "embedded newlines not allowed");
                }
                writer.write(arg);
                writer.newLine();
            }

            writer.flush();

            // Should there be a timeout on this?
            ProcessStartResult result = new ProcessStartResult();
            result.pid = inputStream.readInt();
            if (result.pid < 0) {
                throw new ZygoteStartFailedEx("fork() failed");
            }
            result.usingWrapper = inputStream.readBoolean();
            return result;
        } catch (IOException ex) {
            zygoteState.close();
            throw new ZygoteStartFailedEx(ex);
        }
    }

可以發(fā)現(xiàn)其最終調(diào)用了Zygote并通過socket通信的方式讓Zygote進(jìn)程fork除了一個(gè)新的進(jìn)程吱涉,并根據(jù)我們剛剛傳遞的"android.app.ActivityThread"字符串,反射出該對(duì)象并執(zhí)行ActivityThread的main方法驶乾。這樣我們所要啟動(dòng)的應(yīng)用進(jìn)程這時(shí)候其實(shí)已經(jīng)啟動(dòng)了邑飒,但是還沒有執(zhí)行相應(yīng)的初始化操作。

為什么我們平時(shí)都將ActivityThread稱之為ui線程或者是主線程级乐,這里可以看出,應(yīng)用進(jìn)程被創(chuàng)建之后首先執(zhí)行的是ActivityThread的main方法县匠,所以我們將ActivityThread成為主線程风科。

好了撒轮,這時(shí)候我們看一下ActivityThread的main方法的實(shí)現(xiàn)邏輯。

public static void main(String[] args) {
        ...
        Process.setArgV0("<pre-initialized>");

        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        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");
    }

在main方法中主要執(zhí)行了一些初始化的邏輯贼穆,并且創(chuàng)建了一個(gè)UI線程消息隊(duì)列题山,這也就是為什么我們可以在主線程中隨意的創(chuàng)建Handler而不會(huì)報(bào)錯(cuò)的原因,這里提出一個(gè)問題故痊,大家可以思考一下:子線程可以創(chuàng)建Handler么顶瞳?可以的話應(yīng)該怎么做?
然后執(zhí)行了ActivityThread的attach方法愕秫,這里我們看一下attach方法執(zhí)行了那些邏輯操作慨菱。

private void attach(boolean system) {
    ...
    final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
    ...
}

剛剛我們已經(jīng)分析過ActivityManagerNative是ActivityManagerService的Binder client,所以這里調(diào)用了attachApplication實(shí)際上就是通過Binder機(jī)制調(diào)用了ActivityManagerService的attachApplication戴甩,具體調(diào)用的過程符喝,我們看一下ActivityManagerService是如何實(shí)現(xiàn)的:

@Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }

可以發(fā)現(xiàn)其回調(diào)了attachApplicationLocked方法,我們看一下這個(gè)方法的實(shí)現(xiàn)邏輯甜孤。

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {

        ...
        // See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
        ...

        return true;
    }

該方法執(zhí)行了一系列的初始化操作协饲,這樣我們整個(gè)應(yīng)用進(jìn)程已經(jīng)啟動(dòng)起來了。終于可以開始activity的啟動(dòng)邏輯了缴川,O(∩_∩)O哈哈~


<strong><font size="6">五:執(zhí)行啟動(dòng)Acitivity</font></strong>

<font color="red">
ActivityStackSupervisor.attachApplicationLocked()
ActivityStackSupervisor.realStartActivityLocked()
IApplicationThread.scheduleLauncherActivity()
ActivityThread.sendMessage()
ActivityThread.H.sendMessage()
ActivityThread.H.handleMessage()
ActivityThread.handleLauncherActivity()
ActivityThread.performLauncherActivity()
Instrumentation.callActivityOnCreate()
Activity.onCreate()
ActivityThread.handleResumeActivity()
ActivityThread.performResumeActivity()
Activity.performResume()
Instrumentation.callActivityOnResume()
Activity.onResume()
ActivityManagerNative.getDefault().activityResumed(token)
</font>

首先看一下attachApplicationLocked方法的實(shí)現(xiàn):

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFrontStack(stack)) {
                    continue;
                }
                ActivityRecord hr = stack.topRunningActivityLocked(null);
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                  + hr.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisibleLocked(null, 0);
        }
        return didSomething;
    }

可以發(fā)現(xiàn)其內(nèi)部調(diào)用了realStartActivityLocked方法茉稠,通過名字可以知道這個(gè)方法應(yīng)該就是用來啟動(dòng)Activity的,看一下這個(gè)方法的實(shí)現(xiàn)邏輯:

final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {

        ...
            app.forceProcessStateUpTo(mService.mTopProcessState);
            app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
        ...
        return true;
    }

可以發(fā)現(xiàn)與第三步執(zhí)行棧頂Activity onPause時(shí)類似把夸,這里也是通過調(diào)用IApplicationThread的方法實(shí)現(xiàn)的战惊,這里調(diào)用的是scheduleLauncherActivity方法,所以真正執(zhí)行的是ActivityThread中的scheduleLauncherActivity扎即,所以我們看一下ActivityThread中的scheduleLauncherActivity的實(shí)現(xiàn):

@Override
        public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                int procState, Bundle state, PersistableBundle persistentState,
                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

            updateProcessState(procState, false);

            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            r.activityInfo = info;
            r.compatInfo = compatInfo;
            r.state = state;
            r.persistentState = persistentState;

            r.pendingResults = pendingResults;
            r.pendingIntents = pendingNewIntents;

            r.startsNotResumed = notResumed;
            r.isForward = isForward;

            r.profilerInfo = profilerInfo;

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);

            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

好吧吞获,還是那套邏輯,ActivityThread接收到SystemServer進(jìn)程的消息之后會(huì)通過其內(nèi)部的Handler對(duì)象分發(fā)消息谚鄙,經(jīng)過一系列的分發(fā)之后調(diào)用了ActivityThread的handleLaunchActivity方法:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {

        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            Bundle oldState = r.state;
            handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);

            
        }
        ...
    }

可以發(fā)現(xiàn)這里調(diào)用了performLauncherActivity各拷,看名字應(yīng)該就是執(zhí)行Activity的啟動(dòng)操作了。闷营。烤黍。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...

Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            }
        }
        ...

        activity.mCalled = false;
        if (r.isPersistable()) {
           mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
           mInstrumentation.callActivityOnCreate(activity, r.state);
        }
        ...
        if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
        ...
        return activity;
    }

可以發(fā)現(xiàn)這里我們需要的Activity對(duì)象終于是創(chuàng)建出來了,而且他是以反射的機(jī)制創(chuàng)建的傻盟,現(xiàn)在還不太清楚為啥google要以反射的方式創(chuàng)建Activity速蕊,先不看這些,然后在代碼中其調(diào)用Instrumentation的callActivityOnCreate方法娘赴。

public void callActivityOnCreate(Activity activity, Bundle icicle,
            PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }

然后執(zhí)行activity的performCreate方法规哲。。诽表。唉锌。好吧隅肥,都轉(zhuǎn)暈了。袄简。腥放。

final void performCreate(Bundle icicle) {
        onCreate(icicle);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

O(∩_∩)O哈哈~,第二個(gè)生命周期方法出來了绿语,onCreate方法秃症。。吕粹。种柑。

在回到我們的performLaunchActivity方法,其在調(diào)用了mInstrumentation.callActivityOnCreate方法之后又調(diào)用了activity.performStart();方法昂芜,好吧莹规,看一下他的實(shí)現(xiàn)方式:

final void performStart() {
        mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
        mFragments.noteStateNotSaved();
        mCalled = false;
        mFragments.execPendingActions();
        mInstrumentation.callActivityOnStart(this);
        if (!mCalled) {
            throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onStart()");
        }
        mFragments.dispatchStart();
        mFragments.reportLoaderStart();
        mActivityTransitionState.enterReady(this);
    }

好吧,還是通過Instrumentation調(diào)用callActivityOnStart方法:

public void callActivityOnStart(Activity activity) {
        activity.onStart();
    }

然后是直接調(diào)用activity的onStart方法泌神,第三個(gè)生命周期方法出現(xiàn)了良漱,O(∩_∩)O哈哈~

還是回到我們剛剛的handleLaunchActivity方法,在調(diào)用完performLaunchActivity方法之后欢际,其有吊用了handleResumeActivity方法母市,好吧,看名字應(yīng)該是回調(diào)Activity的onResume方法的损趋。

final void handleResumeActivity(IBinder token,
            boolean clearHide, boolean isForward, boolean reallyResume) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();
        mSomeActivitiesChanged = true;

        // TODO Push resumeArgs into the activity for consideration
        ActivityClientRecord r = performResumeActivity(token, clearHide);

        if (r != null) {
            final Activity a = r.activity;

            if (localLOGV) Slog.v(
                TAG, "Resume " + r + " started activity: " +
                a.mStartedActivity + ", hideForNow: " + r.hideForNow
                + ", finished: " + a.mFinished);

            final int forwardBit = isForward ?
                    WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;

            // If the window hasn't yet been added to the window manager,
            // and this guy didn't finish itself or start another activity,
            // then go ahead and add the window.
            boolean willBeVisible = !a.mStartedActivity;
            if (!willBeVisible) {
                try {
                    willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
                            a.getActivityToken());
                } catch (RemoteException e) {
                }
            }
            if (r.window == null && !a.mFinished && willBeVisible) {
                r.window = r.activity.getWindow();
                View decor = r.window.getDecorView();
                decor.setVisibility(View.INVISIBLE);
                ViewManager wm = a.getWindowManager();
                WindowManager.LayoutParams l = r.window.getAttributes();
                a.mDecor = decor;
                l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
                l.softInputMode |= forwardBit;
                if (a.mVisibleFromClient) {
                    a.mWindowAdded = true;
                    wm.addView(decor, l);
                }

            // If the window has already been added, but during resume
            // we started another activity, then don't yet make the
            // window visible.
            } else if (!willBeVisible) {
                if (localLOGV) Slog.v(
                    TAG, "Launch " + r + " mStartedActivity set");
                r.hideForNow = true;
            }

            // Get rid of anything left hanging around.
            cleanUpPendingRemoveWindows(r);

            // The window is now visible if it has been added, we are not
            // simply finishing, and we are not starting another activity.
            if (!r.activity.mFinished && willBeVisible
                    && r.activity.mDecor != null && !r.hideForNow) {
                if (r.newConfig != null) {
                    r.tmpConfig.setTo(r.newConfig);
                    if (r.overrideConfig != null) {
                        r.tmpConfig.updateFrom(r.overrideConfig);
                    }
                    if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                            + r.activityInfo.name + " with newConfig " + r.tmpConfig);
                    performConfigurationChanged(r.activity, r.tmpConfig);
                    freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig));
                    r.newConfig = null;
                }
                if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
                        + isForward);
                WindowManager.LayoutParams l = r.window.getAttributes();
                if ((l.softInputMode
                        & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                        != forwardBit) {
                    l.softInputMode = (l.softInputMode
                            & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                            | forwardBit;
                    if (r.activity.mVisibleFromClient) {
                        ViewManager wm = a.getWindowManager();
                        View decor = r.window.getDecorView();
                        wm.updateViewLayout(decor, l);
                    }
                }
                r.activity.mVisibleFromServer = true;
                mNumVisibleActivities++;
                if (r.activity.mVisibleFromClient) {
                    r.activity.makeVisible();
                }
            }

            if (!r.onlyLocalRequest) {
                r.nextIdle = mNewActivities;
                mNewActivities = r;
                if (localLOGV) Slog.v(
                    TAG, "Scheduling idle handler for " + r);
                Looper.myQueue().addIdleHandler(new Idler());
            }
            r.onlyLocalRequest = false;

            // Tell the activity manager we have resumed.
            if (reallyResume) {
                try {
                    ActivityManagerNative.getDefault().activityResumed(token);
                } catch (RemoteException ex) {
                }
            }

        } else {
            // If an exception was thrown when trying to resume, then
            // just end this activity.
            try {
                ActivityManagerNative.getDefault()
                    .finishActivity(token, Activity.RESULT_CANCELED, null, false);
            } catch (RemoteException ex) {
            }
        }
    }

可以發(fā)現(xiàn)其resumeActivity的邏輯調(diào)用到了performResumeActivity方法患久,我們來看一下performResumeActivity是如何實(shí)現(xiàn)的。

public final ActivityClientRecord performResumeActivity(IBinder token,
            boolean clearHide) {
        ActivityClientRecord r = mActivities.get(token);
        if (localLOGV) Slog.v(TAG, "Performing resume of " + r
                + " finished=" + r.activity.mFinished);
        if (r != null && !r.activity.mFinished) {
            if (clearHide) {
                r.hideForNow = false;
                r.activity.mStartedActivity = false;
            }
            try {
                r.activity.onStateNotSaved();
                r.activity.mFragments.noteStateNotSaved();
                if (r.pendingIntents != null) {
                    deliverNewIntents(r, r.pendingIntents);
                    r.pendingIntents = null;
                }
                if (r.pendingResults != null) {
                    deliverResults(r, r.pendingResults);
                    r.pendingResults = null;
                }
                r.activity.performResume();

                EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED,
                        UserHandle.myUserId(), r.activity.getComponentName().getClassName());

                r.paused = false;
                r.stopped = false;
                r.state = null;
                r.persistentState = null;
            } catch (Exception e) {
                if (!mInstrumentation.onException(r.activity, e)) {
                    throw new RuntimeException(
                        "Unable to resume activity "
                        + r.intent.getComponent().toShortString()
                        + ": " + e.toString(), e);
                }
            }
        }
        return r;
    }

在方法體中浑槽,最終調(diào)用了r.activity.performResume();方法蒋失,好吧,這個(gè)方法是Activity中定義的方法桐玻,我們需要在Activity中查看這個(gè)方法的具體實(shí)現(xiàn):

final void performResume() {
        ...
        mInstrumentation.callActivityOnResume(this);
        ...
    }

好吧篙挽,又是熟悉的味道,通過Instrumentation來調(diào)用了callActivityOnResume方法镊靴。铣卡。。

public void callActivityOnResume(Activity activity) {
        activity.mResumed = true;
        activity.onResume();
        
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    am.match(activity, activity, activity.getIntent());
                }
            }
        }
    }

O(∩_∩)O哈哈~偏竟,第四個(gè)生命周期方法出現(xiàn)了煮落,onResume方法。踊谋。蝉仇。

終于回調(diào)onResume方法了,這時(shí)候我們的界面應(yīng)該已經(jīng)展示出來了,照理來說我們的Activity應(yīng)該已經(jīng)啟動(dòng)完成了量淌,但是還沒有骗村,哈哈嫌褪,別著急呀枢。

有一個(gè)問題,Activity a 啟動(dòng) Activity b 會(huì)觸發(fā)那些生命周期方法笼痛?
你可能會(huì)回答裙秋?b的onCreate onStart方法,onResume方法 a的onPause方法和onStop方法缨伊,咦摘刑?對(duì)了onStop方法還沒回調(diào)呢,O(∩_∩)O哈哈~刻坊,對(duì)了缺少的就是對(duì)onStop方法的回調(diào)啊枷恕。

好吧,具體的邏輯我們下一步再說


<strong><font size="6">六:棧頂Activity執(zhí)行onStop方法

<font color="red">
Looper.myQueue().addIdleHandler(new Idler())
Idler.queueIdle()
ActivityManagerNative.getDefault().activityIdle()
ActivityManagerService.activityIdle()
ActivityStackSupervisor.activityIdleInternalLocked()
ActivityStack.stopActivityLocked()
IApplicationThread.scheduleStopActivity()
ActivityThread.scheduleStopActivity()
ActivityThread.sendMessage()
ActivityThread.H.sendMessage()
ActivityThread.H.handleMessage()
ActivityThread.handleStopActivity()
ActivityThread.performStopActivityInner()
ActivityThread.callCallActivityOnSaveInstanceState()
Instrumentation.callActivityOnSaveInstanceState()
Activity.performSaveInstanceState()
Activity.onSaveInstanceState()
Activity.performStop()
Instrumentation.callActivityOnStop()
Activity.onStop()
</font>

回到我們的handleResumeActivity方法谭胚,在方法體最后有這樣的一代碼:

Looper.myQueue().addIdleHandler(new Idler());

這段代碼是異步消息機(jī)制相關(guān)的代碼徐块,我們可以看一下Idler對(duì)象的具體實(shí)現(xiàn):

private class Idler implements MessageQueue.IdleHandler {
        @Override
        public final boolean queueIdle() {
            ActivityClientRecord a = mNewActivities;
            boolean stopProfiling = false;
            if (mBoundApplication != null && mProfiler.profileFd != null
                    && mProfiler.autoStopProfiler) {
                stopProfiling = true;
            }
            if (a != null) {
                mNewActivities = null;
                IActivityManager am = ActivityManagerNative.getDefault();
                ActivityClientRecord prev;
                do {
                    if (localLOGV) Slog.v(
                        TAG, "Reporting idle of " + a +
                        " finished=" +
                        (a.activity != null && a.activity.mFinished));
                    if (a.activity != null && !a.activity.mFinished) {
                        try {
                            am.activityIdle(a.token, a.createdConfig, stopProfiling);
                            a.createdConfig = null;
                        } catch (RemoteException ex) {
                            // Ignore
                        }
                    }
                    prev = a;
                    a = a.nextIdle;
                    prev.nextIdle = null;
                } while (a != null);
            }
            if (stopProfiling) {
                mProfiler.stopProfiling();
            }
            ensureJitEnabled();
            return false;
        }
    }

這樣當(dāng)Messagequeue執(zhí)行add方法之后就會(huì)回調(diào)其queueIdle()方法,我們可以看到在方法體中其調(diào)用了ActivityManagerNative.getDefault().activityIdle()灾而,好吧胡控,熟悉了Binder機(jī)制以后我們知道這段代碼會(huì)執(zhí)行到ActivityManagerService的activityIdle方法:

@Override
    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
        final long origId = Binder.clearCallingIdentity();
        synchronized (this) {
            ActivityStack stack = ActivityRecord.getStackLocked(token);
            if (stack != null) {
                ActivityRecord r =
                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
                if (stopProfiling) {
                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
                        try {
                            mProfileFd.close();
                        } catch (IOException e) {
                        }
                        clearProfilerLocked();
                    }
                }
            }
        }
        Binder.restoreCallingIdentity(origId);
    }

然后在activityIdle方法中又調(diào)用了ActivityStackSupervisor.activityIdleInternalLocked方法:

final ActivityRecord activityIdleInternalLocked(final IBinder token, boolean fromTimeout,
            Configuration config) {
        ...

        // Stop any activities that are scheduled to do so but have been
        // waiting for the next one to start.
        for (int i = 0; i < NS; i++) {
            r = stops.get(i);
            final ActivityStack stack = r.task.stack;
            if (stack != null) {
                if (r.finishing) {
                    stack.finishCurrentActivityLocked(r, ActivityStack.FINISH_IMMEDIATELY, false);
                } else {
                    stack.stopActivityLocked(r);
                }
            }
        }

        ...

        return r;
    }

可以發(fā)現(xiàn)在其中又調(diào)用了ActivityStack.stopActivityLocked方法:

final void stopActivityLocked(ActivityRecord r) {
        if (DEBUG_SWITCH) Slog.d(TAG_SWITCH, "Stopping: " + r);
        if ((r.intent.getFlags()&Intent.FLAG_ACTIVITY_NO_HISTORY) != 0
                || (r.info.flags&ActivityInfo.FLAG_NO_HISTORY) != 0) {
            ...
                r.app.thread.scheduleStopActivity(r.appToken, r.visible, r.configChangeFlags);
             ...
        }
    }

好吧,又是相同的邏輯通過IApplicationThread.scheduleStopActivity,最終調(diào)用了ActivityThread.scheduleStopActivity()方法旁趟。昼激。。锡搜。

public final void scheduleStopActivity(IBinder token, boolean showWindow,
                int configChanges) {
           sendMessage(
                showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
                token, 0, configChanges);
        }

然后執(zhí)行sendMessage方法橙困,最終執(zhí)行H(Handler)的sendMessage方法,并被H的handleMessge方法接收?qǐng)?zhí)行handleStopActivity方法耕餐。凡傅。。

private void handleStopActivity(IBinder token, boolean show, int configChanges) {
        ...
        performStopActivityInner(r, info, show, true);
        ...
    }

然后我們看一下performStopActivityInner的實(shí)現(xiàn)邏輯:

private void performStopActivityInner(ActivityClientRecord r,
            StopInfo info, boolean keepShown, boolean saveState) {
            ...
            // Next have the activity save its current state and managed dialogs...
            if (!r.activity.mFinished && saveState) {
                if (r.state == null) {
                    callCallActivityOnSaveInstanceState(r);
                }
            }

            if (!keepShown) {
                try {
                    // Now we are idle.
                    r.activity.performStop();
                } catch (Exception e) {
                    if (!mInstrumentation.onException(r.activity, e)) {
                        throw new RuntimeException(
                                "Unable to stop activity "
                                + r.intent.getComponent().toShortString()
                                + ": " + e.toString(), e);
                    }
                }
                r.stopped = true;
            }
        }
    }

好吧蛾方,看樣子在這個(gè)方法中執(zhí)行了兩個(gè)邏輯像捶,一個(gè)是執(zhí)行Activity的onSaveInstance方法一個(gè)是執(zhí)行Activity的onStop方法,我們先看一下callCallActivityOnSaveInstanceState的執(zhí)行邏輯:

private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
        r.state = new Bundle();
        r.state.setAllowFds(false);
        if (r.isPersistable()) {
            r.persistentState = new PersistableBundle();
            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
                    r.persistentState);
        } else {
            mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
        }
    }

好吧桩砰,又是通過Instrumentation來執(zhí)行拓春。。亚隅。

public void callActivityOnSaveInstanceState(Activity activity, Bundle outState,
            PersistableBundle outPersistentState) {
        activity.performSaveInstanceState(outState, outPersistentState);
    }

又間接調(diào)用了Activity的performSaveInstanceState方法:

final void performSaveInstanceState(Bundle outState) {
        onSaveInstanceState(outState);
        saveManagedDialogs(outState);
        mActivityTransitionState.saveState(outState);
        if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
    }

呵呵硼莽,這里調(diào)用到了,我們以前經(jīng)常會(huì)重寫的onSaveInstanceState方法。

然后我們看一下performStopActivityInner中調(diào)用到的Activity方法的performStop方法:

final void performStop() {
        mDoReportFullyDrawn = false;
        mFragments.doLoaderStop(mChangingConfigurations /*retain*/);

        if (!mStopped) {
            if (mWindow != null) {
                mWindow.closeAllPanels();
            }

            if (mToken != null && mParent == null) {
                WindowManagerGlobal.getInstance().setStoppedState(mToken, true);
            }

            mFragments.dispatchStop();

            mCalled = false;
            mInstrumentation.callActivityOnStop(this);
            if (!mCalled) {
                throw new SuperNotCalledException(
                    "Activity " + mComponent.toShortString() +
                    " did not call through to super.onStop()");
            }

            synchronized (mManagedCursors) {
                final int N = mManagedCursors.size();
                for (int i=0; i<N; i++) {
                    ManagedCursor mc = mManagedCursors.get(i);
                    if (!mc.mReleased) {
                        mc.mCursor.deactivate();
                        mc.mReleased = true;
                    }
                }
            }

            mStopped = true;
        }
        mResumed = false;
    }

還是通過Instrumentation來實(shí)現(xiàn)的懂鸵,調(diào)用了它的callActivityOnStop方法偏螺。。

public void callActivityOnStop(Activity activity) {
        activity.onStop();
    }

O(∩_∩)O哈哈~匆光,最后一個(gè)生命周期方法終于出來了套像,onStop().....




<font size="5">總結(jié):</font>

  • Activity的啟動(dòng)流程一般是通過調(diào)用startActivity或者是startActivityForResult來開始的

  • startActivity內(nèi)部也是通過調(diào)用startActivityForResult來啟動(dòng)Activity,只不過傳遞的requestCode小于0

  • Activity的啟動(dòng)流程涉及到多個(gè)進(jìn)程之間的通訊這里主要是ActivityThread與ActivityManagerService之間的通訊

  • ActivityThread向ActivityManagerService傳遞進(jìn)程間消息通過ActivityManagerNative终息,ActivityManagerService向ActivityThread進(jìn)程間傳遞消息通過IApplicationThread夺巩。

  • ActivityManagerService接收到應(yīng)用進(jìn)程創(chuàng)建Activity的請(qǐng)求之后會(huì)執(zhí)行初始化操作,解析啟動(dòng)模式周崭,保存請(qǐng)求信息等一系列操作柳譬。

  • ActivityManagerService保存完請(qǐng)求信息之后會(huì)將當(dāng)前系統(tǒng)棧頂?shù)腁ctivity執(zhí)行onPause操作,并且IApplication進(jìn)程間通訊告訴應(yīng)用程序繼承執(zhí)行當(dāng)前棧頂?shù)腁ctivity的onPause方法续镇;

  • ActivityThread接收到SystemServer的消息之后會(huì)統(tǒng)一交個(gè)自身定義的Handler對(duì)象處理分發(fā)美澳;

  • ActivityThread執(zhí)行完棧頂?shù)腁ctivity的onPause方法之后會(huì)通過ActivityManagerNative執(zhí)行進(jìn)程間通訊告訴ActivityManagerService,棧頂Actiity已經(jīng)執(zhí)行完成onPause方法摸航,繼續(xù)執(zhí)行后續(xù)操作制跟;

  • ActivityManagerService會(huì)繼續(xù)執(zhí)行啟動(dòng)Activity的邏輯,這時(shí)候會(huì)判斷需要啟動(dòng)的Activity所屬的應(yīng)用進(jìn)程是否已經(jīng)啟動(dòng)忙厌,若沒有啟動(dòng)則首先會(huì)啟動(dòng)這個(gè)Activity的應(yīng)用程序進(jìn)程凫岖;

  • ActivityManagerService會(huì)通過socket與Zygote繼承通訊,并告知Zygote進(jìn)程fork出一個(gè)新的應(yīng)用程序進(jìn)程逢净,然后執(zhí)行ActivityThread的mani方法哥放;

  • 在ActivityThead.main方法中執(zhí)行初始化操作,初始化主線程異步消息爹土,然后通知ActivityManagerService執(zhí)行進(jìn)程初始化操作甥雕;

  • ActivityManagerService會(huì)在執(zhí)行初始化操作的同時(shí)檢測(cè)當(dāng)前進(jìn)程是否有需要?jiǎng)?chuàng)建的Activity對(duì)象,若有的話胀茵,則執(zhí)行創(chuàng)建操作脯燃;

  • ActivityManagerService將執(zhí)行創(chuàng)建Activity的通知告知ActivityThread萝风,然后通過反射機(jī)制創(chuàng)建出Activity對(duì)象,并執(zhí)行Activity的onCreate方法,onStart方法引几,onResume方法峰锁;

  • ActivityThread執(zhí)行完成onResume方法之后告知ActivityManagerService onResume執(zhí)行完成步咪,開始執(zhí)行棧頂Activity的onStop方法侣诺;

  • ActivityManagerService開始執(zhí)行棧頂?shù)膐nStop方法并告知ActivityThread;

  • ActivityThread執(zhí)行真正的onStop方法熄浓;

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末情臭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌俯在,老刑警劉巖竟秫,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異跷乐,居然都是意外死亡肥败,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門劈猿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拙吉,“玉大人潮孽,你說我怎么就攤上這事揪荣。” “怎么了往史?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵仗颈,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我椎例,道長(zhǎng)挨决,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任订歪,我火速辦了婚禮脖祈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘刷晋。我一直安慰自己盖高,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布眼虱。 她就那樣靜靜地躺著喻奥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪捏悬。 梳的紋絲不亂的頭發(fā)上撞蚕,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音过牙,去河邊找鬼甥厦。 笑死,一個(gè)胖子當(dāng)著我的面吹牛寇钉,可吹牛的內(nèi)容都是我干的刀疙。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼摧莽,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼庙洼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤油够,失蹤者是張志新(化名)和其女友劉穎蚁袭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體石咬,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡揩悄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鬼悠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片删性。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖焕窝,靈堂內(nèi)的尸體忽然破棺而出蹬挺,到底是詐尸還是另有隱情,我是刑警寧澤它掂,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布巴帮,位于F島的核電站,受9級(jí)特大地震影響虐秋,放射性物質(zhì)發(fā)生泄漏榕茧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一客给、第九天 我趴在偏房一處隱蔽的房頂上張望用押。 院中可真熱鬧,春花似錦靶剑、人聲如沸蜻拨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽官觅。三九已至,卻和暖如春阐污,著一層夾襖步出監(jiān)牢的瞬間休涤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工笛辟, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留功氨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓手幢,卻偏偏與公主長(zhǎng)得像捷凄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子围来,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • Zygote是什么跺涤?有什么作用匈睁? Android系統(tǒng)底層基于Linux Kernel, 當(dāng)Kernel啟動(dòng)過程會(huì)創(chuàng)...
    Mr槑閱讀 2,804評(píng)論 4 18
  • 一個(gè)Android系統(tǒng)的手機(jī),面對(duì)桌面一大堆的應(yīng)用圖標(biāo)桶错,我們隨便點(diǎn)擊一個(gè)應(yīng)用圖標(biāo)航唆,打開該應(yīng)用,然后就進(jìn)行了...
    黑衣_fy閱讀 3,288評(píng)論 0 6
  • 引論 處理器管理 存儲(chǔ)管理 文件管理 設(shè)備管理 并發(fā)進(jìn)程
    灰斗兒閱讀 150評(píng)論 0 0
  • 有時(shí)候生活難得有靈感或者感悟的片段院刁,所以才有了《隨想》的這個(gè)主題糯钙,故而《隨想》這個(gè)主題的內(nèi)容是非常瑣碎的退腥。因?yàn)槲蚁?..
    SlientWheat閱讀 178評(píng)論 0 0