android Activity启动流程(6)

/ android / 没有评论 / 717浏览

用到的代码文件

frameworks/base/core/java/android/app/ActivityThread.java
frameworks/base/core/java/android/app/ActivityThread.java类中定义的ApplicationThread类
frameworks/base/core/java/android/app/ApplicationThreadNative.java
frameworks/base/core/java/android/app/Instrumentation.java
frameworks/base/core/java/android/app/Activity.java

代码执行流程图

android activity 查看大图

模块编译

mm frameworks/base/ -> system/framework/framework.jar

android activity启动流程

下面的代码是以android N(api 24)为基础。

承接上文android Activity启动流程(5)

ApplicationThread类中的scheduleLaunchActivity()方法执行。
ApplicationThread类继承自ApplicationThreadNative类,ApplicationThreadNative类又继承自Binder类。

// we use token to identify this activity without having to send the
// activity itself back to the activity manager. (matters more with ipc)
@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) {

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

H类也是定义在ActivityThread类中的内部类。
H类进行处理消息LAUNCH_ACTIVITY。

class H extends Handler{
    ......
    public void handleMessage(Message msg) {
        ......
        switch (msg.what) {
            case LAUNCH_ACTIVITY: {
                log("handler case LAUNCH_ACTIVITY");
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, 
                      "activityStart");
                final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

                r.packageInfo = getPackageInfoNoCheck(
                        r.activityInfo.applicationInfo, r.compatInfo);
                /*
                  * 进入这里
                  */
                handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                //jackywei biao.wei@tcl.com Task3170761,Temporarily closed
                if (false && mIsNoOdex) {
                    Toast.makeText(mInitialApplication.getApplicationContext(), 
                        "The optimizer is running in the background,It mybe run slowly.", 
                        Toast.LENGTH_LONG).show();
                }

                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
            }
       }
   ......
}

下面进入ActivityThread类中的handleLaunchActivity()方法。

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
   /*ActivityRecord{98a9aa3 token=android.os.BinderProxy@833b1a0
     {com.jrdcom.filemanager/com.jrdcom.filemanager.activity.FileBrowserActivity}}*/
    log("ActivityClientRecord r : "+r);
    log("customIntent : "+customIntent); // null
    log("reason : "+reason); //LAUNCH_ACTIVITY
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    if (r.profilerInfo != null) {
        mProfiler.setProfiler(r.profilerInfo);
        mProfiler.startProfiling();
    }

    // Make sure we are running with the most recent config.
    handleConfigurationChanged(null, null);

    if (localLOGV) Slog.v(
        TAG, "Handling launch of " + r);

    // Initialize before creating the activity
    WindowManagerGlobal.initialize();
    /*
      * 进入这里
      */
    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) { // -> true
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

        if (!r.activity.mFinished && r.startsNotResumed) { // -> false
            // The activity manager actually wants this one to start out paused, because it
            // needs to be visible but isn't in the foreground. We accomplish this by going
            // through the normal startup (because activities expect to go through onResume()
            // the first time they run, before their window is displayed), and then pausing it.
            // However, in this case we do -not- need to do the full pause cycle (of freezing
            // and such) because the activity manager assumes it can just retain the current
            // state it has.
            performPauseActivityIfNeeded(r, reason);

            // We need to keep around the original state, in case we need to be created again.
            // But we only do this for pre-Honeycomb apps, which always save their state when
            // pausing, so we can not have them save their state when restarting from a paused
            // state. For HC and later, we want to (and can) let the state be saved as the
            // normal part of stopping the activity.
            if (r.isPreHoneycomb()) {
                r.state = oldState;
            }
        }
    } else {
        // If there was an error, for any reason, tell the activity manager to stop us.
        try {
            ActivityManagerNative.getDefault()
                .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                        Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
}

下面进入ActivityThread类中的performLaunchActivity()方法。
这个方法主要是创建一个Activity实例并执行onCreate()和onStart()生命周期方法。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ......
    ActivityInfo aInfo = r.activityInfo;
    //aInfo : ActivityInfo{d384da5 com.jrdcom.filemanager.activity.FileBrowserActivity}
    log("aInfo : "+aInfo);
    if (r.packageInfo == null) { // -> false
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }

    ComponentName component = r.intent.getComponent();
    if (component == null) { // -> false
        component = r.intent.resolveActivity(
            mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }

    if (r.activityInfo.targetActivity != null) { // -> false
        component = new ComponentName(r.activityInfo.packageName,
                r.activityInfo.targetActivity);
    }

    Activity activity = null;
    try {
        /*
         * 这里是创建一个activity
         * 这里传了一个ClassLoader,反射构造一个activity。
         */
        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);
        }
    }

    try {
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        //app : com.jrdcom.filemanager.FileManagerApplication
        log("app : "+app.getClass().getName());
        /*ActivityRecord{98a9aa3 token=android.os.BinderProxy@833b1a0
         {com.jrdcom.filemanager/com.jrdcom.filemanager.activity.FileBrowserActivity}}*/
        log( "Performing launch of " + r);
        log(
                r + ": app=" + app
                + ", appName=" + app.getPackageName()
                + ", pkg=" + r.packageInfo.getPackageName()
                + ", comp=" + r.intent.getComponent().toShortString()
                + ", dir=" + r.packageInfo.getAppDir());
        /*
        ActivityRecord{98a9aa3 token=android.os.BinderProxy@833b1a0
            {com.jrdcom.filemanager/com.jrdcom.filemanager.activity.FileBrowserActivity}}:
            app=com.jrdcom.filemanager.FileManagerApplication@5e549d2,
            appName=com.jrdcom.filemanager, pkg=com.jrdcom.filemanager,
            comp={com.jrdcom.filemanager/com.jrdcom.filemanager.activity.FileBrowserActivity},
            dir=/system/priv-app/FileManager/FileManager.apk
        */

        if (activity != null) { // -> true
            Context appContext = createBaseContextForActivity(r, activity);
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (r.overrideConfig != null) { // -> true
                config.updateFrom(r.overrideConfig);
            }
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            Window window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) { // -> false
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window);

            if (customIntent != null) { // -> false
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) { // -> true
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            if (r.isPersistable()) { // -> false
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                /*
                 * 从这里开始调用onCreate()
                 */
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            if (!activity.mCalled) {// -> false
                throw new SuperNotCalledException(
                    "Activity " + r.intent.getComponent().toShortString() +
                    " did not call through to super.onCreate()");
            }
            r.activity = activity;
            r.stopped = true;
            if (!r.activity.mFinished) { // -> true
                /*
                 * 从这里开始调用onStart()
                 */
                activity.performStart();
                r.stopped = false;
            }
            if (!r.activity.mFinished) { // -> true
                if (r.isPersistable()) { // -> false
                    if (r.state != null || r.persistentState != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                r.persistentState);
                    }
                } else if (r.state != null) { // -> false
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                }
            }
            if (!r.activity.mFinished) { // -> true
                activity.mCalled = false;
                if (r.isPersistable()) { // ->false
                    mInstrumentation.callActivityOnPostCreate(activity, r.state,
                            r.persistentState);
                } else {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onPostCreate()");
                }
            }
        }
        r.paused = true;

        mActivities.put(r.token, r);

    } catch (SuperNotCalledException e) {
        throw e;

    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to start activity " + component
                + ": " + e.toString(), e);
        }
    }

    return activity;
}

下面进入Instrumentation类的callActivityOnCreate()方法。

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

下面进入Activity类的performCreate()方法。

final void performCreate(Bundle icicle) {
    restoreHasCurrentPermissionRequest(icicle);
    /*
     * onCreate生命周期方法
     */
    onCreate(icicle);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
}

下面是performLaunchActivity()方法中调用“activity.performStart();”。

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

    // This property is set for all builds except final release
    boolean isDlwarningEnabled = SystemProperties.getInt("ro.bionic.ld.warning", 0) == 1;
    boolean isAppDebuggable =
            (mApplication.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;

    if (isAppDebuggable || isDlwarningEnabled) {
        String dlwarning = getDlWarning();
        if (dlwarning != null) {
            String appName = getApplicationInfo().loadLabel(getPackageManager())
                    .toString();
            String warning = "Detected problems with app native libraries\n" +
                             "(please consult log for detail):\n" + dlwarning;
            if (isAppDebuggable) {
                  new AlertDialog.Builder(this).
                      setTitle(appName).
                      setMessage(warning).
                      setPositiveButton(android.R.string.ok, null).
                      setCancelable(false).
                      show();
            } else {
                Toast.makeText(this, appName + "\n" + warning, Toast.LENGTH_LONG).show();
            }
        }
    }

    mActivityTransitionState.enterReady(this);
}

下面是Instrumentation类中的callActivityOnStart()方法。

public void callActivityOnStart(Activity activity) {
    /*
     * 生命周期方法
     */
    activity.onStart();
}

下面是上面ActivityThread类中handleLaunchActivity中继续执行handleResumeActivity();

final void handleResumeActivity(IBinder token,
        boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
        return;
    }

    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;
    /*
      * 进入这里
      */
    r = performResumeActivity(token, clearHide, reason);
    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) {
                throw e.rethrowFromSystemServer();
            }
        }
        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 (r.mPreserveWindow) {
                a.mWindowAdded = true;
                r.mPreserveWindow = false;
                // Normally the ViewRoot sets up callbacks with the Activity
                // in addView->ViewRootImpl#setView. If we are instead reusing
                // the decor view we have to notify the view root that the
                // callbacks may have changed.
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) {
                    impl.notifyChildRebuilt();
                }
            }
            if (a.mVisibleFromClient && !a.mWindowAdded) {
                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, false /* force */);

        // 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) {
                performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                        + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
                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) {
                throw ex.rethrowFromSystemServer();
            }
        }

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

下面进入ActivityThread类中的performResumeActivity()方法。

public final ActivityClientRecord performResumeActivity(IBinder token,
        boolean clearHide, String reason) {
    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();

            // If there is a pending local relaunch that was requested when the activity was
            // paused, it will put the activity into paused state when it finally happens.
            // Since the activity resumed before being relaunched, we don't want that to happen,
            // so we need to clear the request to relaunch paused.
            for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) {
                final ActivityClientRecord relaunching = mRelaunchingActivities.get(i);
                if (relaunching.token == r.token
                        && relaunching.onlyLocalRequest && relaunching.startsNotResumed) {
                    relaunching.startsNotResumed = false;
                }
            }

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

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

下面进入Activity类中的performResume()方法。

final void performResume() {
    performRestart();

    mFragments.execPendingActions();

    mLastNonConfigurationInstances = null;

    mCalled = false;
    /*
     * 进入这里
     */
    // mResumed is set by the instrumentation
    mInstrumentation.callActivityOnResume(this);
    if (!mCalled) {
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onResume()");
    }

    // invisible activities must be finished before onResume() completes
    if (!mVisibleFromClient && !mFinished) {
        Log.w(TAG, "An activity without a UI must call finish() before onResume() completes");
        if (getApplicationInfo().targetSdkVersion
                > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
            throw new IllegalStateException(
                    "Activity " + mComponent.toShortString() +
                    " did not call finish() prior to onResume() completing");
        }
    }

    // Now really resume, and install the current status bar and menu.
    mCalled = false;

    mFragments.dispatchResume();
    mFragments.execPendingActions();

    onPostResume();
    if (!mCalled) {
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onPostResume()");
    }
}

下面进入Instrumentation类中的callActivityOnResume()方法。

public void callActivityOnResume(Activity activity) {
    activity.mResumed = true;
    /**
     * onResume()生命周期方法。
     */
    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());
            }
        }
    }
}

至此一个Activity就启动起来了。