美文网首页Java&Android日更补完计划
Activity工作过程(1)-《Andoid开发艺术探索》《深

Activity工作过程(1)-《Andoid开发艺术探索》《深

作者: 埃赛尔 | 来源:发表于2017-03-27 21:24 被阅读53次

    在《为什么子线程不能更新UI》中有一部分特别不能理解,就是我怎么知道ViewRootImpl是在哪里,是什么时候创建的?

    这里就需要研习Activity的工作过程,这里主要分析Activity的启动过程,通过本节读者可以对Activity的启动过程有个感性的认识至于启动模式以及任务栈等概念本节中并未涉及,读者感兴趣可以查看相关的代码细节

    /**
    
    * @hide
    
    */
    
    @Override
    
    public void startActivityForResult(
    
    String who, Intent intent, int requestCode, @Nullable Bundle options) {
    
    ···
    //先看重点
    Instrumentation.ActivityResult ar =mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, who,intent, requestCode, options);
    ···
    }
    

    这个InstrumentationmInstrumentation

    /**
    
    * Base class for implementing application instrumentation code.  When running
    
    * with instrumentation turned on, this class will be instantiated for you
    
    * before any of the application code, allowing you to monitor all of the
    
    * interaction the system has with the application.  An Instrumentation
    
    * implementation is described to the system through an AndroidManifest.xml's
    
    *<instrumentation>tag.
    *关于这个类释义大概是这样:实现应用程序代码的基类。当运行 随着 Instrumentation 运行,这个类将为您实例化 在任何应用程序代码之前,允许您监视所有的 交互系统与应用。
    
    */
    
    public classInstrumentation
    

    来看具体方法吧:

    public ActivityResult execStartActivity(
    
    Context who, IBinder contextThread, IBinder token, Activity target,
    
    Intent intent, int requestCode, Bundle options) {
    
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    
    Uri referrer = target != null ? target.onProvideReferrer() : null;
    
    if (referrer != null) {
    
    intent.putExtra(Intent.EXTRA_REFERRER, referrer);
    
    }
    
    if (mActivityMonitors != null) {
    
    synchronized (mSync) {
    
    final int N = mActivityMonitors.size();
    
    for (int i=0; i
    
    final ActivityMonitor am = mActivityMonitors.get(i);
    
    if (am.match(who, null, intent)) {
    
    am.mHits++;
    
    if (am.isBlocking()) {
    
    return requestCode >= 0 ? am.getResult() : null;
    
    }
    
    break;
    
    }
    
    }
    
    }
    
    }
    
    try {
    
    intent.migrateExtraStreamToClipData();
    
    intent.prepareToLeaveProcess(who);
    
    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;
    
    }
    

    ActivityManagerNative

    public abstract class ActivityManagerNative extends Binder implements IActivityManager

    getDefault():

    没错在这里 ,这里?!这是什么鬼?

    private static final Singleton gDefault = new Singleton() {
    
    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;
    
    }
    
    };
    

    Singleton:它是个单例的封装类,第一次调用它的get()时它会通过create的方法初始化 IActivityManager对象实际上是获取ActivityManagerService

    这里就涉及到了binder机制,使用ServiceManager.getService("activity") 这里就是告诉ServiceManager 把ActivityManagerService给我(细说的话,就是:看看Binder机制吧)

    再次调用的时候则直接返回之前创建的对象

    ActivityManagerService才是IActivityManager的实现类

    public final class ActivityManagerService extends ActivityManagerNative

    implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback

    ActivityManagerService ,ActivityThread 这两个类,为activity的正常运行提供了不可或缺的支持(我需要找更多的资料来梳理这三个类的关系,和工作逻辑-从Activity的创建到销毁,这两个类都发挥了什么样的助力?)

    看ActivityManagerService的startActivity都做了什么,

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

    哦,调用了startActivityAsUser(),那继续走:

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

    这里给userId 赋值然后调用了这个类:

    /**

    • Controller for interpreting how and then launching activities.

    • This class collects all the logic for determining how an intent and flags should be turned into

    • an activity and associated task and stack.

    */

    class ActivityStarter

    这个类存放了所有将 intent 和 flags 转换为一个activity 相关的任务和堆栈的逻辑

    final int startActivityMayWait(...){//参数比较多我就不粘出来了以梳理流程为主
    
    ...
    
    //生成startActivity所需要的ResolveInfo
    
    ResolveInfo rInfo = mSupervisor.resolveIntent(intent, resolvedType, userId);
    
    ...
    
    //生成startActivity所需要的ActivityInfo
    
    ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);
    
    ...
    
    //生成一系列需要的参数
    
    int res =startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
    
    aInfo, rInfo, voiceSession, voiceInteractor,
    
    resultTo, resultWho, requestCode, callingPid,
    
    callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
    
    options, ignoreTargetSecurity, componentSpecified, outRecord, container,
    
    inTask);
    
    }
    

    接下来看startActivityLocked():

    try {
    
    mService.mWindowManager.deferSurfaceLayout();
    
    err =startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
    
    true, options, inTask);
    
    } finally {
    
    mService.mWindowManager.continueSurfaceLayout();
    
    }
    
    ...
    
    if (res == ActivityManager.START_SUCCESS) {
    
    mSupervisor.mWaitingActivityLaunched.add(outResult);
    
    do {
    
    try {
    
    mService.wait();
    
    } catch (InterruptedException e) {
    
    }
    
    } while (outResult.result != START_TASK_TO_FRONT
    
    && !outResult.timeout && outResult.who == null);
    
    if (outResult.result == START_TASK_TO_FRONT) {
    
    res = START_TASK_TO_FRONT;
    
    }
    
    ...
    

    这里之前基本上就是对activity的权限进行校验,结果返回在res中如果:

    根据标识步步校验,返回,不同的方法校验的范围也不一样,如果出现错误,不同方法返回的异常也不一样,方便定位问题是什么类型的问题。

    startActivityUnchecked():

    mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);

    这个方法里,基本上是根据Intent的flag对activity进行处理,涉及到栈之类的操作

    ActivityStack mTargetStack

    /**
    
    * State and management of a single stack of activities. 专门用来管理activity 状态和栈
    
    */
    
    final class ActivityStack
    
    final void startActivityLocked(ActivityRecord r, boolean newTask, boolean keepCurTransition,
    
    ActivityOptions options) {
    
    ...
    
    }
    

    然后。。。真多,有点微醉,我就拿起了《Andoid开发艺术探索》看了起来 发现了一个疑点,没错是疑点,

    2916442-515efb97369d9e79.jpg

    没辙 掏出《深入解析Android5.0系统》也得到相同的结论

    说好的方法呢??

    mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,

    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,

    profilerInfo, null, null, bOptions, false, userId, null, null);

    为啥我的源码长这样???

    看到我的SDK版本我也挺尴尬的 我的版本号是25. 其实这也说明安卓7.0的时候activity的源码已经进行了修改 但是具体处理逻辑是没有发生改变的

    因为在内部实现逻辑讲解这方面《深入解析Android5.0系统》已经算是很深入的进行了讲解,我也不给大家献丑了,我能做的只是尽量全的把这一部分展示给大家,共同学习对比参照。

    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, int userId, IActivityContainer iContainer, TaskRecord inTask) {
    
    // Refuse possible leaked file descriptors
    
    if (intent != null && intent.hasFileDescriptors()) {
    
    throw new IllegalArgumentException("File descriptors passed in Intent");
    
    }
    
    boolean componentSpecified = intent.getComponent() != null;
    
    // Don't modify the client's object! 创建一个新的对象方便改动
    
    intent = new Intent(intent);
    
    // Collect information about the target of the Intent. 获取启动的avtivity的信息
    
    ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags,
    
    profilerInfo, userId);
    
    ···
    
    //得到Activity的信息后继续启动Activity
    
    int res =startActivityLocked(caller, intent, resolvedType, aInfo,
    
    voiceSession, voiceInteractor, resultTo, resultWho,
    
    requestCode, callingPid, callingUid, callingPackage,
    
    realCallingPid, realCallingUid, startFlags, options,
    
    componentSpecified, null, container, inTask);
    
    Binder.restoreCallingIdentity(origId);
    
    if (stack.mConfigWillChange) {
    
    // If the caller also wants to switch to a new configuration,
    
    // do so now.  This allows a clean switch, as we are waiting
    
    // for the current activity to pause (so we will not destroy
    
    // it), and have not yet started the next activity.
    
    mService.enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
    
    "updateConfiguration()");
    
    stack.mConfigWillChange = false;
    
    if (DEBUG_CONFIGURATION) Slog.v(TAG,
    
    "Updating to new configuration after starting activity.");
    
    mService.updateConfigurationLocked(config, null, false, false);
    
    }
    
    //如果需要返回结果
    
    if (outResult != null) {
    
    outResult.result = res;
    
    if (res == ActivityManager.START_SUCCESS) {
    
    mWaitingActivityLaunched.add(outResult);
    
    do {
    
    try {
    
    mService.wait();//等待应用进程中Activity的启动完成
    
    } catch (InterruptedException e) {
    
    }
    
    } while (!outResult.timeout && outResult.who == null);
    
    }
    
    ···
    
    return res;
    
    }
    
    }
    

    进到这里来了: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 componentSpecified, ActivityRecord[] outActivity, ActivityContainer container,
    
    TaskRecord inTask) {
    
    int err = ActivityManager.START_SUCCESS;
    
    ProcessRecord callerApp = null;
    
    if (caller != null) {
    
    callerApp = mService.getRecordForAppLocked(caller);//得到调用进程的信息
    
    ···
    
    }
    
    ···//对错误进行检查打印log并返回
    
    final int startAnyPerm = mService.checkPermission(
    
    START_ANY_ACTIVITY, callingPid, callingUid);//检查调用者的权限
    
    final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
    
    callingUid, aInfo.applicationInfo.uid, aInfo.exported);
    
    ···
    
    //检查防火墙是否屏蔽了该intent(防火墙的规则是通过/data/system/ifw 目录下的文件设置的可以让系统禁止使用某intent)
    
    boolean abort = !mService.mIntentFirewall.checkStartActivity(intent, callingUid,
    
    callingPid, resolvedType, aInfo.applicationInfo);
    
    if (mService.mController != null) {
    
    try {
    
    // The Intent we give to the watcher has the extra data
    
    // stripped off, since it can contain private information.
    
    //将Activity启动的消息通知监听系统Activity变动的接口IActivityController
    
    Intent watchIntent = intent.cloneFilter();
    
    abort |= !mService.mController.activityStarting(watchIntent,
    
    aInfo.applicationInfo.packageName);
    
    } catch (RemoteException e) {
    
    mService.mController = null;
    
    }
    
    }
    
    ···
    
    //创建一个ActivityRecord对象
    
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
    
    intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
    
    requestCode, componentSpecified, this, container, options);
    
    if (outActivity != null) {
    
    outActivity[0] = r;
    
    }
    
    //获取当前接受用户输入的ActivityStack
    
    final ActivityStack stack = getFocusedStack();
    
    if (voiceSession == null && (stack.mResumedActivity == null
    
    || stack.mResumedActivity.info.applicationInfo.uid != callingUid)) {
    
    //如果需要经常切换进程,则检查是否有权限切换
    
    if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid,
    
    realCallingPid, realCallingUid, "Activity start")) {
    
    //现在不能切换进程,吧Activity放入mPendingActivityLaunches
    
    PendingActivityLaunch pal =
    
    new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
    
    mPendingActivityLaunches.add(pal);
    
    ActivityOptions.abort(options);
    
    return ActivityManager.START_SWITCHES_CANCELED;
    
    }
    
    }
    
    if (mService.mDidAppSwitch) {
    
    // This is the second allowed switch since we stopped switches,
    
    // so now just generally allow switches.  Use case: user presses
    
    // home (switches disabled, switch to home, mDidAppSwitch now true);
    
    // user taps a home icon (coming from home so allowed, we hit here
    
    // and now allow anyone to switch again).
    
    mService.mAppSwitchesAllowedTime = 0;
    
    } else {
    
    mService.mDidAppSwitch = true;//打开允许进程切换的开关
    
    }
    
    doPendingActivityLaunchesLocked(false);//启动挂起等待的activity
    
    //继续启动当前Activity
    
    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
    
    startFlags, true, options, inTask);
    
    if (err < 0) {
    
    // If someone asked to have the keyguard dismissed on the next
    
    // activity start, but we are not actually doing an activity
    
    // switch...  just dismiss the keyguard now, because we
    
    // probably want to see whatever is behind it.
    
    notifyActivityDrawnForKeyguard();
    
    }
    
    return err;
    
    }
    

    /** The stack containing the launcher app. Assumed to always be attached to

    • Display.DEFAULT_DISPLAY. */

    privateActivityStackmHomeStack;

    /** The stack currently receiving input or launching the next activity. */

    privateActivityStackmFocusedStack;

    mHomeStack是系统的第一个ActivityStack 对象,包含了Home应用的Task就位于mHomeStack中,mFocusedStack则指向系统中位于前台的ActivityStack对象,getFocusedStack()将返回前台的ActivityStack对象

    startActivityUncheckedLocked()方法主要是通过判断intent的flag和activity的属性来确定Activity的task

    resumeTopActivitiesLocked(targetStack, null, options);

    resumeTopActivitiesLocked():

    boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
    
    Bundle targetOptions) {
    
    if (targetStack == null) {
    
    targetStack = getFocusedStack();
    
    }
    
    // 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 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;
    
    }
    

    终于换了一个类:ActivityStack类然而这个类的resumeTopActivityLocked()方法在activityservicemanager中很多地方都会调用,主要作用是将为u与站定的activity显示出来,这时当Activity(通过变量mResumeActivity引用)还显示在屏幕上。

    ActivityStack:

    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
    
    if (inResumeTopActivity) {
    
    // Don't even start recursing.
    
    return false;
    
    }
    
    boolean result = false;
    
    try {
    
    // Protect against recursion.
    
    inResumeTopActivity = true;
    
    result =resumeTopActivityInnerLocked(prev, options);
    
    } finally {
    
    inResumeTopActivity = false;
    
    }
    
    return result;
    
    }
    
    resumeTopActivityInnerLocked(prev, options);重点在这里
    
    
    
    final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
    
    ···
    
    cancelInitializingActivities();
    
    // Find the first activity that is not finishing.
    
    //next表示要启动的activity
    
    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 = mStackSupervisor.mUserLeaving;
    
    mStackSupervisor.mUserLeaving = false;
    
    final TaskRecord prevTask = prev != null ? prev.task : null;
    
    if (next == null) {
    
    // There are no more activities!  Let's just start up the
    
    // Launcher...
    
    //如果当前task没有Activity,显示HomeActivity
    
    ActivityOptions.abort(options);
    
    if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
    
    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
    
    // Only resume home if on home display
    
    final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
    
    HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
    
    return isOnHomeDisplay() &&
    
    mStackSupervisor.resumeHomeStackTask(returnTaskType, prev);
    
    }
    
    next.delayedResume = false;
    
    // If the top activity is the resumed one, nothing to do.
    
    //如果当前的activity是要启动的activity直接返回
    
    if (mResumedActivity == next && next.state == ActivityState.RESUMED &&
    
    mStackSupervisor.allResumedActivitiesComplete()) {
    
    // Make sure we have executed any pending transitions, since there
    
    // should be nothing left to do at this point.
    
    mWindowManager.executeAppTransition();
    
    mNoAnimActivities.clear();
    
    ActivityOptions.abort(options);
    
    if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Top activity resumed " + next);
    
    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
    
    // Make sure to notify Keyguard as well if it is waiting for an activity to be drawn.
    
    mStackSupervisor.notifyActivityDrawnForKeyguard();
    
    return false;
    
    }
    
    final TaskRecord nextTask = next.task;
    
    ···
    
    // 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.isSleepingOrShuttingDown()
    
    && mLastPausedActivity == next
    
    && mStackSupervisor.allPausedActivitiesComplete()) {
    
    // Make sure we have executed any pending transitions, since there
    
    // should be nothing left to do at this point.
    
    mWindowManager.executeAppTransition();
    
    mNoAnimActivities.clear();
    
    ActivityOptions.abort(options);
    
    if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Going to sleep and all paused");
    
    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
    
    return false;
    
    }
    
    // Make sure that the user who owns this activity is started.  If not,
    
    // we will just leave it as is because someone should be bringing
    
    // another user's activities to the top of the stack.
    
    if (mService.mStartedUsers.get(next.userId) == null) {//检查用户ID
    
    ···
    
    return false;
    
    }
    
    // The activity may be waiting for stop, but that is no longer
    
    // appropriate for it.
    
    //将启动的activity从Stopping,GoingtoSleep,waitingVisible等队列中移除
    
    mStackSupervisor.mStoppingActivities.remove(next);
    
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    
    next.sleeping = false;
    
    mStackSupervisor.mWaitingVisibleActivities.remove(next);
    
    if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);
    
    // If we are currently pausing an activity, then don't do anything
    
    // until that is done.
    
    if (!mStackSupervisor.allPausedActivitiesComplete()) {
    
    ···//如果系统还有暂停的Activity先退出
    
    return false;
    
    }
    
    ···
    
    // We need to start pausing the current activity so the top one
    
    // can be resumed...
    
    //暂停后台的Activity
    
    boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
    
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
    
    if (mResumedActivity != null) {
    
    //暂停当前的Activity
    
    pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
    
    if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
    
    }
    
    if (pausing) {
    
    //如果系统还有正在暂停的Activity 退出
    
    if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,
    
    "resumeTopActivityLocked: Skip resume: need to start pausing");
    
    // At this point we want to put the upcoming activity's process
    
    // at the top of the LRU list, since we know we will be needing it
    
    // very soon and it would be a waste to let it get killed if it
    
    // happens to be sitting towards the end.
    
    if (next.app != null && next.app.thread != null) {
    
    mService.updateLruProcessLocked(next.app, true, null);
    
    }
    
    if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
    
    return true;
    
    }
    
    ···
    
    if (prev != null && prev != next) {
    
    //如果Activity不可见,把前一个Activity加入mWaitingVisibleActivities
    
    if (!prev.waitingVisible && next != null && !next.nowVisible) {
    
    prev.waitingVisible = true;
    
    mStackSupervisor.mWaitingVisibleActivities.add(prev);
    
    if (DEBUG_SWITCH) Slog.v(
    
    TAG, "Resuming top, waiting visible to hide: " + prev);
    
    } else {
    
    // The next activity is already visible, so hide the previous
    
    // activity's windows right now so we can show the new one ASAP.
    
    // We only do this if the previous is finishing, which should mean
    
    // it is on top of the one being resumed so hiding it quickly
    
    // is good.  Otherwise, we want to do the normal route of allowing
    
    // the resumed activity to be shown so we can decide if the
    
    // previous should actually be hidden depending on whether the
    
    // new one is found to be full-screen or not.
    
    if (prev.finishing) {
    
    //如果Activity已经是可见状态,把前一个Activity隐藏起来
    
    mWindowManager.setAppVisibility(prev.appToken, false);
    
    if (DEBUG_SWITCH) Slog.v(TAG, "Not waiting for visible to hide: "
    
    + prev + ", waitingVisible="
    
    + (prev != null ? prev.waitingVisible : null)
    
    + ", nowVisible=" + next.nowVisible);
    
    } else {
    
    if (DEBUG_SWITCH) Slog.v(TAG, "Previous already visible but still waiting to hide: "
    
    + prev + ", waitingVisible="
    
    + (prev != null ? prev.waitingVisible : null)
    
    + ", nowVisible=" + next.nowVisible);
    
    }
    
    }
    
    }
    
    ···
    
    // 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.
    
    boolean anim = true;
    
    ··· //调用WindowManagerService方法来处理Activity的显示
    
    ActivityStack lastStack = mStackSupervisor.getLastStack();
    
    if (next.app != null && next.app.thread != null) {
    
    if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next);
    
    // This activity is now becoming visible.
    
    //如果activity存在只需要显示出来
    
    mWindowManager.setAppVisibility(next.appToken, true);
    
    ···
    
    try {
    
    //如果这个Activity中海油等待返回的结果,先发送结果
    
    // Deliver all pending results.
    
    ArrayList a = next.results;
    
    if (a != null) {
    
    final int N = a.size();
    
    if (!next.finishing && N > 0) {
    
    if (DEBUG_RESULTS) Slog.v(
    
    TAG, "Delivering results to " + next
    
    + ": " + a);
    
    next.app.thread.scheduleSendResult(next.appToken, a);
    
    }
    
    }
    
    if (next.newIntents != null) {
    
    next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
    
    }
    
    ···
    
    //调用ActivityThread的OnResume()
    
    next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
    
    mService.isNextTransitionForward(), resumeAnimOptions);
    
    mStackSupervisor.checkReadyForSleepLocked();
    
    ···
    
    //如果activity所在的应用还没启动,先启动应用
    
    mStackSupervisor.startSpecificActivityLocked(next, true, false);
    
    ···
    
    return true;
    
    }
    

    总结就是:

    如果Activity所在的应用已经启动,这里将会scheduleResumeActivity调度ActivityThread走onresume()其实就是activity走了OnResume()

    如果应用还没有启动,或者刚刚启动,则调用

    startSpecificActivityLocked()

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

    如果发现应用进程没有启动则调用

    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,

    "activity", r.intent.getComponent(), false, false, true);来启动进程;

    否则

    realStartActivityLocked(r, app, andResume, checkConfig);

    继续执行:

    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,

    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),

    r.compat, r.task.voiceInteractor, app.repProcState, r.icicle, r.persistentState,

    results, newIntents, !andResume, mService.isNextTransitionForward(),

    profilerInfo);

    呼~ scheduleLaunchActivity()这个方法将会调用Activity类的OnCreate()方法 没错到了在这里状态已经由staractivity变成了 Activity的onCreate()

    让我们用一张图做一下纪念吧:

    2916442-cc79023509b10e49.png

    当然,这里的生命周期不够准确,主要描述其中在Activity创建之前的调用关系。

    下一节主要描述ActivityStack是通过怎么样的方式和Activity关联起来。

    相关文章

      网友评论

        本文标题:Activity工作过程(1)-《Andoid开发艺术探索》《深

        本文链接:https://www.haomeiwen.com/subject/bgcdottx.html