Activity启动流程(4)

Activity启动流程(3)中,Launcher已经执行了onPause方法,并告知了ActivityManagerService,本篇就分析下ActivityManagerService收到Launcher的通知后会执行的操作。

ActivityManagerService类activityPaused

public final void activityPaused(IBinder token) {
    ......
    mMainStack.activityPaused(token, false);
    ......
}  

ActivityStack类activityPaused

很简单,主要就是调用了ActivityStack的activityPaused方法,其中token指向的之Launcher的ActivityRecord。

inal void activityPaused(IBinder token, boolean timeout) {
    ActivityRecord r = null;
    synchronized (mService) {
        int index = indexOfTokenLocked(token);
        if (index >= 0) {
            r = mHistory.get(index);
            mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
            if (mPausingActivity == r) {
                if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
                        + (timeout ? " (due to timeout)" : " (pause complete)"));
                r.state = ActivityState.PAUSED;
                completePauseLocked();
            } else {
                ......
            }
        }
    }
}  

由于此时mPausingActivity与Launcher相同,故completePauseLocked会被执行。

ActivityStack类completePauseLocked

private final void completePauseLocked() {
    ActivityRecord prev = mPausingActivity;
    ......
    if (prev != null) {
        if (prev.finishing) {
            ......
        } else if (prev.app != null) {
            .....
            if (prev.configDestroy) {
               ......
            } else {
                mStoppingActivities.add(prev);
                ......
                } else {
                    ......
                }
            }
        } else {
            ......
        }
        mPausingActivity = null;
    }

    if (!mService.isSleeping()) {
        resumeTopActivityLocked(prev);
    } else {
        ......
    }
    ......
}  

由于隐藏了无关和启动流程无关的代码,故流程已经很清晰了,prev指向的正是Launcher的ActivityRecord。接下来resumeTopActivity会被执行。

ActivityStack类resumeTopActivity

final boolean resumeTopActivityLocked(ActivityRecord prev) {
    // 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) {
       ......
    }

    next.delayedResume = false;

    // If the top activity is the resumed one, nothing to do.
    if (mResumedActivity == next && next.state == ActivityState.RESUMED) {
        ......
    }

    // If we are sleeping, and there is no resumed activity, and the top
    // activity is paused, well that is the state we want.
    if ((mService.mSleeping || mService.mShuttingDown)
           ......
    }

    // The activity may be waiting for stop, but that is no longer
    // appropriate for it.
    ......
    if (mPausingActivity != null) {
        ......
    }
    if (false) {
        ......
    }

    // We need to start pausing the current activity so the top one
    // can be resumed...
    if (mResumedActivity != null) {
       ......
    }

    if (prev != null && prev != next) {
        if (!prev.waitingVisible && next != null && !next.nowVisible) {
            ......
        } else {
           ......
            } else {
                ......
            }
        }
    }

    // Launching this app's activity, make sure the app is no longer
    // considered stopped.
   ......
    // We are starting up the next activity, so tell the window manager
    // that the previous one will be hidden soon.  This way it can know
    // to ignore it when computing the desired screen orientation.
    if (prev != null) {
        if (prev.finishing) {
            ......
        }
        if (false) {
            ......
        }
    } else if (mHistory.size() > 1) {
        ......
    }

    if (next.app != null && next.app.thread != null) {
        ......
    } else {
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
            ......
        startSpecificActivityLocked(next, true, true);
    }

    return true;
}  

要理解这段代码,需要知道目前Launcher和目标Activity的状态。执行到这段代码时,Launcher已经处于结束了onPause方法的执行,正处于paused的状态,目前处于最Activity栈 栈顶的Activity为目标Activity,但是此时目标Activity的实例还未被初始化,目标Activity所在应用的进程也未被新建。next指向的就是目标Activity,prev指向的是Launcher,next.app指向目标Activity所在的进程,由于此时应用进程未被创建,故next.app = null,将会执行startSpecificActivityLocked(next, true, true)

ActivityStack类startSpecificActivityLocked

private final 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);

    ......

    if (app != null && app.thread != null) {
        ......
        }

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

由于应用程序为启动,故app = null,接下来会执行startProcessLocked

ActivityManagerService类startProcessLocked

final ProcessRecord startProcessLocked(String processName,
        ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
    ProcessRecord app = getProcessRecordLocked(processName, info.uid);
    ......
    if (app != null && app.pid > 0) {
        //代码块1
        ......
    }

    String hostingNameStr = hostingName != null
            ? hostingName.flattenToShortString() : null;

    if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
        //代码块2
        ......
        }
    } else {
        ......
        }
    }

    if (app == null) {
        //代码块3
        app = newProcessRecordLocked(null, info, processName);
        mProcessNames.put(processName, info.uid, app);
    } else {
        ......
    }

    // If the system is not ready yet, then hold off on starting this
    // process until it is.
    if (!mProcessesReady
            && !isAllowedWhileBooting(info)
            && !allowWhileBooting) {
        ......
    }

    startProcessLocked(app, hostingType, hostingNameStr);
    return (app.pid != 0) ? app : null;
}

进入该函数执行时,目标Activity还没有执行onCreate方法,目标Activity所在的进程也没有被创建,故app = null;intentFlags = 0,故代码块2不会被执行,app = null,故代码块3也不会被执行,最终函数的调用会走到startProcessLocked的重载方法中,app是调用newProcessRecordLocked方法后返回的一个进程实例,hostingType=”Activity”,hostingNameStr是目标Activity的全限定名,如com.example.Activity1

ActivityManagerService类startProcessLocked

private final void startProcessLocked(ProcessRecord app,
        String hostingType, String hostingNameStr) {
    if (app.pid > 0 && app.pid != MY_PID) {
        ......
    }

    ......

    try {
        int uid = app.info.uid;
        int[] gids = null;
        try {
            gids = mContext.getPackageManager().getPackageGids(
                    app.info.packageName);
        } catch (PackageManager.NameNotFoundException e) {
            Slog.w(TAG, "Unable to retrieve gids", e);
        }
        if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
            if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
                    && mTopComponent != null
                    && app.processName.equals(mTopComponent.getPackageName())) {
                uid = 0;
            }
            if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
                    && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
                uid = 0;
            }
        }
        int debugFlags = 0;
        if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
            debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
            // Also turn on CheckJNI for debuggable apps. It's quite
            // awkward to turn on otherwise.
            debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
        }
        // Run the app in safe mode if its manifest requests so or the
        // system is booted in safe mode.
        if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
            Zygote.systemInSafeMode == true) {
            debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
        }
        if ("1".equals(SystemProperties.get("debug.checkjni"))) {
            debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
        }
        if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
            debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
        }
        if ("1".equals(SystemProperties.get("debug.assert"))) {
            debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
        }

        // Start the process.  It will either succeed and return a result containing
        // the PID of the new process, or else throw a RuntimeException.
        Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
                app.processName, uid, uid, gids, debugFlags,
                app.info.targetSdkVersion, null);

        ......
}     

去掉了不影响流程的代码,代码的流程就显得很清晰。这部分代码的主要工作就是收集目标Activity所在包的gid信息,设置调试标识debugFlags,然后去启动android.app.ActivityThread类,并调用ActivityThread的main方法。

ActivityThread表示应用的UI线程,也就是主线程,看下main方法里面做了什么操作。

ActivityThread类main

public static void main(String[] args) {
    ......
    Looper.prepareMainLooper();
    if (sMainThreadHandler == null) {
        sMainThreadHandler = new Handler();
    }

    ActivityThread thread = new ActivityThread();
    thread.attach(false);

    if (false) {
        Looper.myLooper().setMessageLogging(new
                LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}  

好吧,为什么我们可以在Activity里面随意new Handler,这下就很明白了,main方法的逻辑很简单,就是新建了消息队列,并开始了Looper循环。下一步要看得函数就是thread.attach(false)

ActivityThread类attach

private void attach(boolean system) {
    sThreadLocal.set(this);
    mSystemThread = system;
    if (!system) {
        //代码块1
        ......
        IActivityManager mgr = ActivityManagerNative.getDefault();
        try {
            mgr.attachApplication(mAppThread);
        } catch (RemoteException ex) {
            // Ignore
        }
    } else {
        //代码块2
       ......
    }

    ......
}

由于应用不是系统应用,故代码块1会被执行,而代码块2不会被执行。代码块2是Binder夸进程调用,故调用最终会转移到ActivityManangerService中,到ActivityManangerService找下attachApplication方法的实现。

ActivityManagerService类attachApplication

public final void attachApplication(IApplicationThread thread) {
    synchronized (this) {
        ......
        attachApplicationLocked(thread, callingPid);
        ......
    }
}  

调用又到了attachApplicationLocked方法,thread代表已经启动的应用进程,callPid代表已经启动的进程的pid,这里已经启动的进程是指目标Activity所在的进程。

ActivityManagerService类attachApplicationLocked

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

    // Find the application record that is being attached...  either via
    // the pid if we are running in multiple processes, or just pull the
    // next app record if we are emulating process with anonymous threads.
    ProcessRecord app;
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            app = mPidsSelfLocked.get(pid);
        }
    } else {
        app = null;
    }

    if (app == null) {
        ......
        return false;
    }

    // If this application record is still attached to a previous
    // process, clean it up now.
    if (app.thread != null) {
        handleAppDiedLocked(app, true, true);
    }

    // Tell the process all about itself.

    if (localLOGV) Slog.v(
            TAG, "Binding process pid " + pid + " to record " + app);

    String processName = app.processName;
    ......
    app.thread = thread;
    app.curAdj = app.setAdj = -100;
    app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
    app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
    app.forcingToForeground = null;
    app.foregroundServices = false;
    app.hasShownUi = false;
    app.debugging = false;

    ......

    boolean badApp = false;
    boolean didSomething = false;
    ......
    ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
    if (hr != null && normalMode) {
        if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
                && processName.equals(hr.processName)) {
            try {
                if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.w(TAG, "Exception in new application when starting activity "
                      + hr.intent.getComponent().flattenToShortString(), e);
                badApp = true;
            }
        } else {
            ......
        }
    }

   ......
}  

代码执行到这里时,目标Activity所在应用的Process已经新建完成,这部分的主要功能是取出已经新建的Process并对Process的属性进行设置。最后调用mMainStack.topRunningActivityLocked(null)方法获取当前在栈顶的Activity的对象ActivityRecord,执行mMainStack.realStartActivityLocked(hr, app, true, true)方法去启动目标Activity。

ActivityStack类realStartActivity

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

    ......
    try {
        if (app.thread == null) {
            throw new RemoteException();
        }
        List<ResultInfo> results = null;
        List<Intent> newIntents = null;
        if (andResume) {
            results = r.results;
            newIntents = r.newIntents;
        }
        ......
        r.sleeping = false;
        r.forceNewConfig = false;
        showAskCompatModeDialogLocked(r);
        r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
        String profileFile = null;
        ParcelFileDescriptor profileFd = null;
        boolean profileAutoStop = false;
        if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
            ......
        }
        app.hasShownUi = true;
        app.pendingUiClean = true;
        ......
       app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
                System.identityHashCode(r), r.info, mService.mConfiguration,
                r.compat, r.icicle, results, newIntents, !andResume,
                mService.isNextTransitionForward(), profileFile, profileFd,
                profileAutoStop);
     ......
}

这段代码最终调用app.thread.scheduleLaunchActivity,这个调用是夸进程调用,最终的调用会在ActivityThread.ApplicationThread.scheduleLaunchActivity执行。

ActivityThread.Application类scheduleLaunchActivity

public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
            ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
            Bundle state, List<ResultInfo> pendingResults,
            List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
            String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
        ActivityClientRecord r = new ActivityClientRecord();

        r.token = token;
        r.ident = ident;
        r.intent = intent;
        r.activityInfo = info;
        r.compatInfo = compatInfo;
        r.state = state;

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

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

        r.profileFile = profileName;
        r.profileFd = profileFd;
        r.autoStopProfiler = autoStopProfiler;

        updatePendingConfiguration(curConfig);

        queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
    }  

又看到了queueOrSendMessage方法,没有印象的亲可以朝前看。看下这里的H为Handler类型,看下handleMessage的函数处理逻辑。

case LAUNCH_ACTIVITY: {
                ActivityClientRecord r = (ActivityClientRecord)msg.obj;

                r.packageInfo = getPackageInfoNoCheck(
                        r.activityInfo.applicationInfo, r.compatInfo);
                handleLaunchActivity(r, null);
            } break;  

函数的调用又转到了handleLaunchActivity

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ......
    Activity a = performLaunchActivity(r, customIntent);
    ......
}

哈哈,到这里感觉马上就要看到Activity的onCreate函数了,去看看performLaunchActivity

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

    ActivityInfo aInfo = r.activityInfo;
    ......

    ComponentName component = r.intent.getComponent();
    ......
    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);
        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);

        ......

        if (activity != null) {
            ContextImpl appContext = new ContextImpl();
            appContext.init(r.packageInfo, r.token, this);
            appContext.setOuterContext(activity);
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config);

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

            activity.mCalled = false;
            mInstrumentation.callActivityOnCreate(activity, r.state);
            ......
            r.activity = activity;
            r.stopped = true;
            if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }
            if (!r.activity.mFinished) {
                if (r.state != null) {
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                }
            }
            if (!r.activity.mFinished) {
                activity.mCalled = false;
                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;
}

哎呀我去,终于看到了callActivityOnCreate,终于到Activity开始执行onCreate方法了。好了,这部分的流程算是看完了,接下来我会总结下Activity的启动流程。

猜你喜欢

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