码迷,mamicode.com
首页 > 其他好文 > 详细

Activity组件启动过程(二)

时间:2015-08-30 17:38:03      阅读:282      评论:0      收藏:0      [点我收藏+]

标签:

前面启动过程图:(源码基于Android5.1)

技术分享

技术分享
    获得到ActivityManagerProxy的实例后,会通过ActivityManagerProxy将启动Activity组件的相关信息写入到Parcel对象data中,然后发送一个类型为START_ACTIVITY_TRANSACTION的进程间通信请求给AMS(ActivityManagerService),接下来的工作的会在AMS进程中进行完成。

    接下来的启动过程总结为下图:
技术分享
    处理START_ACTIVITY_TRANSACTION类型的通信请求,需要调用ActivityManagerService.startActivity方法。

1、ActivityManagerService类

public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback
 可以看到ActivityManagerService类继承ActivityManagerNative类的。来看其处理事件请求函数onTransact:

1)ActivityManagerService#onTransact:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java*/
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    if (code == SYSPROPS_TRANSACTION) {
        ...
    }
    try {
        /** 可以看到除了SYSPROPS_TRANSACTION类型的事件,其他都交由
         *  父类ActivityManagerNative的onTransact函数处理 **/
        return super.onTransact(code, data, reply, flags);
    } catch (RuntimeException e) {
        ...
    }
}
    可以看到事件处理最终是调用其父类ActivityManagerNative.onTransact函数中进行处理。


2)ActivityManagerNative.onTransact

/** @path: \frameworks\base\core\java\android\app\ActivityManagerNative.java*/
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
        throws RemoteException {
    switch (code) {
        // 前面所涉及到的START_ACTIVITY_TRANSACTION类型请求对应此响应
        case START_ACTIVITY_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder b = data.readStrongBinder();
            IApplicationThread app = ApplicationThreadNative.asInterface(b);
            String callingPackage = data.readString();
            Intent intent = Intent.CREATOR.createFromParcel(data);
            String resolvedType = data.readString();
            ....
            /** 可以看到这里响应函数主体为startActivity **/
            int result = startActivity(app, callingPackage, intent, resolvedType,
                    resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
            reply.writeNoException();
            reply.writeInt(result);
            return true;
        }
    }
}

    最终START_ACTIVITY_TRANSACTION类型请求响应的函数为调用startActivity函数;可以看到ActivityManagerService类中对startActivity进行了Override;故这里调用的是ActivityManagerService.startActivity方法;


3)ActivityManagerService#startActivity

/*** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java*/
@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) {
    /** 转而调用startActivityAsUser */
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options, UserHandle.getCallingUserId());

}

@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.
    /** @value mStackSupervisor = new ActivityStackSupervisor(this); */
    return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
            resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
            profilerInfo, null, null, options, userId, null, null);

}

最终调用ActivityStackSupervisor.startActivityMayWait函数来继续启动Activity组件。(在Android4.4之前都是使用ActivityStack类而非ActivityStackSupervisor)


4)ActivityStackSupervisor#startActivityMayWait

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java*/
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) {
    boolean componentSpecified = intent.getComponent() != null;

    // 拷贝构造函数,指向新地址,避免修改原client对象
    intent = new Intent(intent);

    // 解析目标Intent中的信息,保存到ActivityInfo类中,据此来确定目标Activity
    ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);

    ActivityContainer container = (ActivityContainer)iContainer;
    synchronized (mService) {
    // 获取caller相关进程的PID与UID
        final int realCallingPid = Binder.getCallingPid();
        final int realCallingUid = Binder.getCallingUid();
        int callingPid;
        if (callingUid >= 0) {
            callingPid = -1;
        } else if (caller == null) {
            callingPid = realCallingPid;
            callingUid = realCallingUid;
        } else {
            callingPid = callingUid = -1;
        }

        final ActivityStack stack;
        ....

        if (aInfo != null && (aInfo.applicationInfo.flags&ApplicationInfo.FLAG_CANT_SAVE_STATE) != 0) {
            // This may be a heavy-weight process!  Check to see if we already
            // have another, different heavy-weight process running.
            /*** 判断目标进程是否是重量级的(heavy-weight) ***/
            if (aInfo.processName.equals(aInfo.applicationInfo.packageName)) {
            /*** 如果当前系统中已经存在的重量级进程(mService.mHeavyWeightProcess)
             *   不是即将要启动的那个,就要给Intent重新赋值 ***/
                if (mService.mHeavyWeightProcess != null &&
                        (mService.mHeavyWeightProcess.info.uid != aInfo.applicationInfo.uid ||
                                !mService.mHeavyWeightProcess.processName.equals(aInfo.processName))) {
                    int appCallingUid = callingUid;
                    if (caller != null) {
                        ProcessRecord callerApp = mService.getRecordForAppLocked(caller);
                        if (callerApp != null) {
                            appCallingUid = callerApp.info.uid;
                        } else {
                            ActivityOptions.abort(options);
                            return ActivityManager.START_PERMISSION_DENIED;
                        }
                    }
                    ......
                }
            }
        }

        // 继续执行该函数,启动Activity组价
        int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                voiceSession, voiceInteractor, resultTo, resultWho,
                requestCode, callingPid, callingUid, callingPackage,
                realCallingPid, realCallingUid, startFlags, options,
                componentSpecified, null, container, inTask);

        .......

        /*** 当WaitResult outResult不为空时,还需要将res写入到ourResult中 **/
        if (outResult != null) {
            outResult.result = res;
            ........
        }

        return res;
    }
}
 上面的函数较为复杂,重要的进行Intent进行匹配检查;然后进行重量级进程判断;进而调用startActivityLocked进一步执行启动工作。


5)ActivityStackSupervisor#startActivityLocked

/**@path: \frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java*/
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;

    /*** 类似于ActivityRecord类,每一个进程也对应一个ProcessRecord类来描述其信息 **/
    ProcessRecord callerApp = null;
    if (caller != null) {
        // @value final ActivityManagerService
        mService;
        /**  ActivityManagerService.getRecordForAppLocked用以获取caller对应的ProcessRecord
         *  由于caller实际指向的是Launcher组件所运行在的进程中的一个ApplicationThread对象,则
         *  callerApp(ProcessRecord)实际指向的则就是Launcher组件对应的进程**/
        callerApp = mService.getRecordForAppLocked(caller);
        if (callerApp != null) {
            // 设置进程PID,UID
            callingPid = callerApp.pid;
            callingUid = callerApp.info.uid;
        } else {
            /** 需要确保调用者caller本身进行存在,否则直接返回START_PERMISSION_DENIED错误 **/
            ......
            err = ActivityManager.START_PERMISSION_DENIED;
        }
    }

    /** 这里使用sourceRecord、resultRecord来实现
     *  FLAG_ACTIVITY_FORWARD_RESULT的跨越式传递作用 **/
    // 每一个已经启动的Activity组件都使用一个ActivityRecord对象来描述
    ActivityRecord sourceRecord = null;
    ActivityRecord resultRecord = null;

    // 获得Intent的启动标志
    final int launchFlags = intent.getFlags();

    /** 处理FLAG_ACTIVITY_FORWARD_RESULT **/
    /** 跨越式传递:比如当Activity1正常启动了Activity2,而Activity2启动Activity3时使用了这个标志,当Activity3调用
     *
     setResult时,result会传给最初的Activity1,而非通常情况下的Activity2 */
    if ((launchFlags & Intent.FLAG_ACTIVITY_FORWARD_RESULT) != 0 && sourceRecord != null) {
        if (requestCode >= 0) {
            ActivityOptions.abort(options);
            return ActivityManager.START_FORWARD_AND_REQUEST_CONFLICT;
        }
        // 将result target由source activity传递给最新被启动的activity
        // 为实现跨越式传递,就需要将启动Activity3的caller设置为Activity1
        resultRecord = sourceRecord.resultTo;
        resultWho = sourceRecord.resultWho;
        requestCode = sourceRecord.requestCode;
        sourceRecord.resultTo = null;
        if (resultRecord != null) {
            resultRecord.removeResultsLocked(sourceRecord, resultWho, requestCode);
        }
        if (sourceRecord.launchedFromUid == callingUid) {
            callingPackage = sourceRecord.launchedFromPackage;
        }
    }

    ......

    final ActivityStack resultStack = resultRecord == null ? null : resultRecord.task.stack;

    if (err != ActivityManager.START_SUCCESS) {
        if (resultRecord != null) {
            resultStack.sendActivityResultLocked(-1, resultRecord, resultWho, requestCode,
                    Activity.RESULT_CANCELED, null);
        }
        ActivityOptions.abort(options);
        return err;
    }

    /** 启动权限判断,判断调用者是否有权限来启动指定Activity */
    final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid, callingUid);
    final int componentPerm = mService.checkComponentPermission(aInfo.permission, callingPid,
                    callingUid, aInfo.applicationInfo.uid, aInfo.exported);
    .....
    /** 生成ActivityRecord变量,记录当前各项判断结果 **/
    ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
            intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho,
            requestCode, componentSpecified, this, container, options);
    .....

    /** 调用该函数继续向下执行
     **/
    err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
            startFlags, true, options, inTask);

    .....
    return err;
}

    继续来看ActivityStackSupervisor的启动函数startActivityUncheckedLocked;


6)ActivityStackSupervisor#startActivityUncheckedLocked
/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java*/
final int startActivityUncheckedLocked(ActivityRecord r, ActivityRecord sourceRecord,
                                       IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
                                       boolean doResume, Bundle options, TaskRecord inTask) {
    // 获得Activity的启动模式
   final boolean launchSingleTop = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP;
    final boolean launchSingleInstance = r.launchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE;
    final boolean launchSingleTask = r.launchMode == ActivityInfo.LAUNCH_SINGLE_TASK;

    // 获得启动标志位
    int launchFlags = intent.getFlags();

    /** 和overview screen相关,即手机中的最近任务列表
     *  --总览画面--overview screen,通常也指最近画面,最近任务表,或者是最近app,
     *    它是一个显示最近使用的activitys和tasks的系统级UI。用户可以通过它进行应用导航,
     *    或者是选择一个task 进行 resume,当然也可以将一个task或者是activity从该列表中移除
     *  --在Android L 中,一个activity里面会包含多个事件,故一个Activity中会有多个文件
     *   (document)以task的形式出现在overview screen中
     *
     *  --当你调用ActivityManager.AppTask类中的 startActivity() 方法时,当前的activity
     *    就会创建一个新的document,并给该document 传递一个 Intent 。 如果在给Intent 中添加
     *    addFlags() 方法,并传递 flag:FLAG_ACTIVITY_NEW_DOCUMENT ,系统就会将创建的Activity
     *    作为一个新的task显示在 overview screen中
     *  --注意:标签 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 在 Android 5.0 中已经弃用,替换为:
     *    FLAG_ACTIVITY_NEW_DOCUMENT
     *  --当你创建一个新的document的时候,如果在 Intent 中添加了 FLAG_ACTIVITY_MULTIPLE_TASK
     *    标签,那么系统将会永远新建一个新的task,并把目标Activity设置为该task 的 root,这样就
     *    允许同一个 document 在多个task中打开。
     * **/
    if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0 &&
            (launchSingleInstance || launchSingleTask)) {
        launchFlags &= ~(Intent.FLAG_ACTIVITY_NEW_DOCUMENT | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
    } else {
        switch (r.info.documentLaunchMode) {
            .....
        }
    }

    ....

    /** 处理FLAG_ACTIVITY_NO_USER_ACTION情况,如果该标志位为1,则表示并非是用户主观意愿启动的Activity:
     * 具体情况如来电、闹钟事件等,此时mUserLeaving为false **/
    // We'll invoke onUserLeaving before onPause only if the launching
    // activity did not explicitly state that this is an automated launch.
    mUserLeaving = (launchFlags & Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;

    /** 当caller要求在当前节点not resume,我们将会将其记录起来以便在查询top running activity时skip it **/
    if (!doResume) { // 当前情况下doResume传入参数为true,可以跳过
        r.delayedResume = true;
    }

    // FLAG_ACTIVITY_PREVIOUS_IS_TOP为1表示子Activity要在新的任务中启动
    ActivityRecord notTop = (launchFlags & Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP) != 0 ? r : null;

    /** 如果调用者和被启动的对象是同一个,不不需要重复启动 **/
    if ((startFlags&ActivityManager.START_FLAG_ONLY_IF_NEEDED) != 0) {
        .....
    }

    boolean addingToTask = false;
    TaskRecord reuseTask = null;

    /** 判断是否需要在新的Task中启动Activity **/
    if (sourceRecord == null && inTask != null && inTask.stack != null) {
        final Intent baseIntent = inTask.getBaseIntent();
        final ActivityRecord root = inTask.getRootActivity();
        ....

        // If task is empty, then adopt the interesting intent launch flags in to the
        // activity being started.
        if (root == null) {
            final int flagsOfInterest = Intent.FLAG_ACTIVITY_NEW_TASK
                    | Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT
                    | Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS;
            launchFlags = (launchFlags&~flagsOfInterest) | (baseIntent.getFlags()&flagsOfInterest);
            intent.setFlags(launchFlags);
            inTask.setIntent(r);
            addingToTask = true;
        } else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
            // 当标志位为FLAG_ACTIVITY_NEW_TASK时,则需要启动一个新Task
            addingToTask = false;

        } else {
            addingToTask = true;
        }

        reuseTask = inTask;
    } else {
        inTask = null;
    }

    .....

    // Should this be considered a new task?
    if (r.resultTo == null && inTask == null && !addingToTask
            && (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
        if (isLockTaskModeViolation(reuseTask)) {
            return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
        }
        newTask = true;
        // 这里根据前面的判断是否需要创建新的Task,还是添加到原先的stack中(addToStack标志)
        // 即使需要标志位显示要NewTask,还要判断Activity的专属任务(taskAffinity)是否已经存在
        targetStack = adjustStackFocus(r, newTask);

        if (!launchTaskBehind) {
            targetStack.moveToFront("startingNewTask");
        }
        if (reuseTask == null) {
            r.setTask(targetStack.createTaskRecord(getNextTaskId(),
                            newTaskInfo != null ? newTaskInfo : r.info,
                            newTaskIntent != null ? newTaskIntent : intent,
                            voiceSession, voiceInteractor, !launchTaskBehind /* toTop */),
                    taskToAffiliate);
        } else {
            r.setTask(reuseTask, taskToAffiliate);
        }
        if (!movedHome) {
            if ((launchFlags &
                    (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
                    == (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
                // Caller wants to appear on home activity, so before starting
                // their own activity we will bring home to the front.
                r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
            }
        }
    }
    .....
    ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
    targetStack.mLastPausedActivity = null;

   /** 前面一系列的操作就是要查找到存放Activity的targetStack,然后再调用其startActivityLocked函数进一步启动Activity组件 **/
    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;
}
    上面的一系列操作就是根据Intent的启动标志位等其他信息判断存放Activity组件的目标Stack——targetStack,targetStack的类型是ActivityStack,则接下来调用ActivityStack.startActivityLocked方法。

7、ActivityStack#startActivityLocked

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityStack.java **/
final void startActivityLocked(ActivityRecord r, boolean newTask,
                               boolean doResume, boolean keepCurTransition, Bundle options) {
    .....
    TaskRecord task = null;
    /** 首先需要根据传入参数判读是否是在新的Task任务中启动的Activity组件 **/
    if (!newTask) {
        // 如果是在新的Task中启动的组件,则需要遍历mTaskHistory来获取
        boolean startIt = true;
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            // mTaskHistory用来描述Activity的组件堆栈;(Android4.4之前使用的是mHistory)
            task = mTaskHistory.get(taskNdx);
            if (task.getTopActivity() == null) {
                // All activities in task are finishing.
                continue;
            }
            if (task == r.task) { // 找到当前task
                /** 如果这个task当前对于用户是不可见的,则需要将其添加到mTaskHistory中,并向WMS进行注册(但并不需要启动它) **/
                if (!startIt) {
                    task.addActivityToTop(r);
                    r.putInHistory();
                    mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken,
                            r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen,
                            (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0,
                            r.userId, r.info.configChanges, task.voiceSession != null,
                            r.mLaunchTaskBehind);
                    ....
                    ActivityOptions.abort(options);
                    return;
                }
                break;
            } else if (task.numFullscreen > 0) {
                startIt = false;
            }
        }
    }

    // 这里是新启动了一个Task的情况
    task = r.task;
    /** 将该Activity至于该任务栈的最顶层,并将r添加到history中 **/
    task.addActivityToTop(r);
    task.setFrontOfTask();
    r.putInHistory();

    .......
    if (doResume) {
        /** 这里用来将Activity组件任务栈最顶层的Activity组件激活 **/
        mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
    }
}
 上面主要作用就是将Activity组件添加到任务栈Task的顶层,然后调用mStackSupervisor.resumeTopActivitiesLocked函数来激活该组件;mStackSupervisor的类型:final ActivityStackSupervisor mStackSupervisor;这里又转而调用ActivityStackSupervisor的函数继续启动Activity组件。


8、ActivityStackSupervisor#resumeTopActivitiesLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityStackSupervisor.java **/
boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target, Bundle targetOptions) {
    if (targetStack == null) {
        targetStack = getFocusedStack();
    }
    // Do targetStack first.
    boolean result = false;
    /** 这里其实是个包装函数,最后依然是调用ActivityStack的resumeTopActivityLocked函数 **/
    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;
}
 这里只是做了简单判断,最后又转回到ActivityStack中调用其resumeTopActivitiesLocked方法继续启动;


9、ActivityStack#resumeTopActivitiesLocked方法:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityStack.java **/
/**
 * 确保当前stack栈顶的activity是resumed。
 * @param prev The previously resumed activity, for when in the process
 * of pausing; can be null to call from elsewhere.
 * @return 如果有activity被resumed,则返回true
 */
final boolean resumeTopActivityLocked(ActivityRecord prev) {
    return resumeTopActivityLocked(prev, null);
}

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
    /** 如果Top Activity是resumed的,则无需做任何事 **/
    if (mStackSupervisor.inResumeTopActivity) {
        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;
}
    向下继续调用reusmeTopActivityInnerLocked方法。


10、ActivityStack#reusmeTopActivityInnerLocked

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityStack.java **/
final boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {

    if (!mService.mBooting && !mService.mBooted) {
        // AMS为启动,直接返回
        return false;
    }

    ActivityRecord parent = mActivityContainer.mParentActivity;
    if ((parent != null && parent.state != ActivityState.RESUMED) ||
            !mActivityContainer.isAttachedLocked()) {
        // 如果一个stack,它的parent没有resumed,则也直接返回
        return false;
    }
    cancelInitializingActivities();

    /**  topRunningActivityLocked用来遍历mTaskHistory取出堆栈上面一个
     *  不是出于结束状态即有效的Activity*/
    final 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.
    // mUserLeaving用以标示是否需要向源Activity组件发送一个用户离开事件通知
    final boolean userLeaving = mStackSupervisor.mUserLeaving;
    mStackSupervisor.mUserLeaving = false;

    final TaskRecord prevTask = prev != null ? prev.task : null;

    /** 如果next为null,则只需要启动Launcher主界面(即Android系统无论何时都会有正在运行的Activity,即Launcher) **/
    if (next == null) {
        // There are no more activities!  Let's just start up the
        // Launcher...
        ActivityOptions.abort(options);
        // 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, "noMoreActivities");
    }

    next.delayedResume = false;
    /**  mResumedActivity--系统当前激活的Activity组件
     *   mLastPausedActivity--上一次被中止的Activity组件
     *   mPausingActivity--正在被中止的Activity组件
     **/

    /** If the top activity is the resumed one, nothing to do
     *  如果next即是当前需要启动的Activity组件,并且其状态为resumed,则不需要进行任何操作
     *  表示当前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);
        return false;
    }

    ......

    /** 如果next是上一次被中止的Activity组件,并且系统正要进入关机或者睡眠状态,则直接返回 **/
    if (mService.isSleepingOrShuttingDown()
            && mLastPausedActivity == next
            && mStackSupervisor.allPausedActivitiesComplete()) {
        .....
        return false;
    }

    /** 如果要启动的Activity组件处于stopping状态,这里就需要中止其stop操作 **/
    mStackSupervisor.mStoppingActivities.remove(next);
    mStackSupervisor.mGoingToSleepActivities.remove(next);
    next.sleeping = false;
    mStackSupervisor.mWaitingVisibleActivities.remove(next);

    .....
    /** 检查系统当前是否是正在pause前一个Activity,我们需要等待操作结束,再启动next,因此直接返回
     *  Android4.4之前是基于一个变量mPausingActivity来判断的,这里Android5.1是基于函数
     *  allPausedActivitiesComplete进行判断的,该函数遍历mTaskHistory进查找**/
    if (!mStackSupervisor.allPausedActivitiesComplete()) {
        return false;
    }

    .....

    // We need to start pausing the current activity so the top one
    // can be resumed...
    boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
    boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
    /** mResumedActivity不为null,表示前一个Activity组件还在运行,就需要先执行pause操作startPausingLocked***/
    if (mResumedActivity != null) {
        // 函数1----startPausingLocked用以通知当前运行Activity进入pause状态,以便将焦点让给需要启动的根Activity组件
        pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
    }
    if (pausing) {
        // 在这里将即将启动的Activity组件放在LRU List的顶部,因为我们可能很快就会用到它
        // 如果直接让其killed将会是一种资源浪费
        if (next.app != null && next.app.thread != null) {
            mService.updateLruProcessLocked(next.app, true, null);
        }
        return true;
    }

    ......

    if (prev != null && prev != next) {
        if (!prev.waitingVisible && next != null && !next.nowVisible) {
            /** 如果要启动的Activity是不可见的,则需要将其添加到mWaitingVisibleActivities中 **/
            prev.waitingVisible = true;
            mStackSupervisor.mWaitingVisibleActivities.add(prev);
        } else {
            /** 如果当前Activity已经是可见,所以我们需要立即hide之间的Activity界面以便能够尽快地显示新Activity界面**/
            if (prev.finishing) {
                mWindowManager.setAppVisibility(prev.appToken, false);
            }
        }
    }

    /** 启动新Activity **/
    try {
        AppGlobals.getPackageManager().setPackageStoppedState(next.packageName, false, next.userId);
    } catch (RemoteException e1) {
    } catch (IllegalArgumentException e) {
    }

    /** 将prev的Activity隐藏 **/
    boolean anim = true;
    if (prev != null) {
        if (prev.finishing) {
            if (mNoAnimActivities.contains(prev)) {
                anim = false;
                mWindowManager.prepareAppTransition(AppTransition.TRANSIT_NONE, false);
            } else {
                mWindowManager.prepareAppTransition(prev.task == next.task
                        ? AppTransition.TRANSIT_ACTIVITY_CLOSE
                        : AppTransition.TRANSIT_TASK_CLOSE, false);
            }
            mWindowManager.setAppWillBeHidden(prev.appToken);
            mWindowManager.setAppVisibility(prev.appToken, false);
        }
        ....
    }
    ....

    /** 启动Activity会遇到两种情况:
     * 1、目标Activity所在的进程已经存在
     * 2、Activity的承载进程还未启动**/
    ActivityStack lastStack = mStackSupervisor.getLastStack();
    if (next.app != null && next.app.thread != null) {

        // 显示目标Activity组件
        mWindowManager.setAppVisibility(next.appToken, true);
        next.startLaunchTickingLocked();

        ActivityRecord lastResumedActivity = lastStack == null ? null :lastStack.mResumedActivity;
        ActivityState lastState = next.state;

        mService.updateCpuStats();

        /** 全局变量设置以及统计数据刷新 **/
        next.state = ActivityState.RESUMED;
        mResumedActivity = next;
        next.task.touchActiveTime();
        mService.addRecentTaskLocked(next.task);
        mService.updateLruProcessLocked(next.app, true, null);
        updateLRUListLocked(next);
        mService.updateOomAdjLocked();

        .....

        if (notUpdated) {
            ActivityRecord nextNext = topRunningActivityLocked(null);
            if (nextNext != next) {
                mStackSupervisor.scheduleResumeTopActivities();
            }
            if (mStackSupervisor.reportResumedActivityLocked(next)) {
                mNoAnimActivities.clear();
                return true;
            }
            return false;
        }

        try {
            .....

            if (next.newIntents != null) {
                next.app.thread.scheduleNewIntent(next.newIntents, next.appToken);
            }
            ......
            /** 函数二----指定目标线程去resume目标Activity---重要函数 ***/
            next.app.thread.scheduleResumeActivity(next.appToken, next.app.repProcState,
                    mService.isNextTransitionForward(), resumeAnimOptions);

            mStackSupervisor.checkReadyForSleepLocked();

        } catch (Exception e) {
           ......
        }

        // From this point on, if something goes wrong there is no way
        // to recover the activity.
        try {
            next.visible = true;
            completeResumeLocked(next);
        } catch (Exception e) {
            ....
        }
        next.stopped = false;

    } else { // 承载进程不存在情况
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
            if (SHOW_APP_STARTING_PREVIEW) {
                mWindowManager.setAppStartingWindow(
                        next.appToken, next.packageName, next.theme,
                        mService.compatibilityInfoForPackageLocked(
                                next.info.applicationInfo),
                        next.nonLocalizedLabel,
                        next.labelRes, next.icon, next.logo, next.windowFlags,
                        null, true);
            }
        }
        /*** 重要函数三--- **/
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }

    return true;
}
函数中有三个重要函数:startPausingLocked、scheduleResumeActivity、startSpecificActivityLocked

版权声明:本文为博主原创文章,未经博主允许不得转载。

Activity组件启动过程(二)

标签:

原文地址:http://blog.csdn.net/woliuyunyicai/article/details/48101627

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!