Android Launcher 啓動簡述

Lanucher就是我們平時的開機後的桌面APP(它其實就是一個APP,沒什麼特別的,看起來有點高大上),作爲APP程序,它也需要啓動自己的Activity界面(因爲桌面是能夠看得見的,有界面的).那麼開機時如何啓動呢?

根據上一篇,開機時SystemServer會將ActivityManagerService啓動,那麼首先就會啓動SystemReady(...)方法.

    public void systemReady(final Runnable goingCallback) {

裏面的程序非常的多,大概判斷了FactoryTest,Binder,SystemUI一些,還有一些記錄信息,但是隻需要看到最後面:

mMainStack.resumeTopActivityLocked(null);

看過前面一篇的,對應上面這句話不會陌生的.接下來轉到ActivityStack類中:不過記住上面傳遞的參數爲null

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

    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        // Find the first activity that is not finishing.
        ActivityRecord next = topRunningActivityLocked(null);

        // Remember how we'll process this pause/resume situation, and ensure
        // that the state is reset however we wind up proceeding.
        final boolean userLeaving = mUserLeaving;
        mUserLeaving = false;

        if (next == null) {
            // There are no more activities!  Let's just start up the
            // Launcher...
            if (mMainStack) {
                ActivityOptions.abort(options);
                return mService.startHomeActivityLocked(mCurrentUser);
            }
        }

前面傳遞的參數爲null,發現參數是ActivityRecord,那麼就是很容易,現在系統裏面還沒有任何運行過的Activity記錄,當然顯而易見,剛開機怎麼可能有運行Activity記錄呢?

那麼下面的程序next==null自然而然就是成立的,然後又要裝到ActivityManagerService類:

boolean startHomeActivityLocked(int userId) {
        if (mHeadless) {
            // Added because none of the other calls to ensureBootCompleted seem to fire
            // when running headless.
            ensureBootCompleted();
            return false;
        }

        if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
                && mTopAction == null) {
            // We are running in factory test mode, but unable to find
            // the factory test app, so just sit around displaying the
            // error message and don't try to start anything.
            return false;
        }
        Intent intent = new Intent(
            mTopAction,
            mTopData != null ? Uri.parse(mTopData) : null);
        intent.setComponent(mTopComponent);
        if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
            intent.addCategory(Intent.CATEGORY_HOME);
        }
        ActivityInfo aInfo =
            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
        if (aInfo != null) {
            intent.setComponent(new ComponentName(
                    aInfo.applicationInfo.packageName, aInfo.name));
            // Don't do this if the home app is currently being
            // instrumented.
            aInfo = new ActivityInfo(aInfo);
            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
                    aInfo.applicationInfo.uid);
            if (app == null || app.instrumentationClass == null) {
                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
                mMainStack.startActivityLocked(null, intent, null, aInfo,
                        null, null, 0, 0, 0, 0, null, false, null);
            }
        }

        return true;
    }


最後的mMainStack.startActivityLocked(...)就會啓動Launcher APP,這個在上面的程序中打印出log信息,後面的startActivityLocked和前一篇的是一樣的了.

private final void startActivityLocked(ActivityRecord r, boolean newTask,
            boolean doResume, boolean keepCurTransition, Bundle options) {
        final int NH = mHistory.size();

        int addPos = -1;
        
        if (!newTask) {
            // If starting in an existing task, find where that is...
            boolean startIt = true;
            for (int i = NH-1; i >= 0; i--) {
                ActivityRecord p = mHistory.get(i);
                if (p.finishing) {
                    continue;
                }

打印log出上面NH的值會是等於0,因爲Launcher是第一個啓動的Activity.

這裏面特別強調的是mHistory是ArrayList<ActivityRecord>,記錄了啓機以後所有Activity的運行狀態信息,每啓動一個Activity就會對應有一個ActivityRecord將其所有的狀態和信息記錄下來,並且將這個new的ActivityRecord添加到mHistory集合中.啓動機器後,mHistory中肯定是空的,所以NH=0.













發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章