startActivity之外,从Recent界面启动Activity也是应用启动的一个重要方式;
而这一切都是从RecentView.java的startTaskActivity方法开始的;
/**
* Starts the activity for the launch task.
*
* @param taskView this is the {@link TaskView} that we are launching from. This can be null if
* we are toggling recents and the launch-to task is now offscreen.
*/
private void startTaskActivity(TaskStack stack, Task task, @Nullable TaskView taskView,
ActivityOptions opts, AppTransitionAnimationSpecsFuture transitionFuture,
int windowingMode, int activityType) {
ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(task.key, opts,
windowingMode, activityType, succeeded -> {
if (succeeded) {
// Keep track of the index of the task launch
int taskIndexFromFront = 0;
int taskIndex = stack.indexOfTask(task);
if (taskIndex > -1) {
taskIndexFromFront = stack.getTaskCount() - taskIndex - 1;
}
EventBus.getDefault().send(new LaunchTaskSucceededEvent(taskIndexFromFront));
} else {
Log.e(TAG, mContext.getString(R.string.recents_launch_error_message, task.title));
// Dismiss the task if we fail to launch it
if (taskView != null) {
taskView.dismissTask();
}
// Keep track of failed launches
EventBus.getDefault().send(new LaunchTaskFailedEvent());
}
}, getHandler());
if (transitionFuture != null) {
mHandler.post(transitionFuture::composeSpecsSynchronous);
}
}
ActivityManagerWrapper是SystemUI内的类;接下来看看它的startActivityFromRecentsAsync方法;
/**
* Starts a task from Recents.
*
* @param resultCallback The result success callback
* @param resultCallbackHandler The handler to receive the result callback
*/
public void startActivityFromRecentsAsync(Task.TaskKey taskKey, ActivityOptions options,
int windowingMode, int activityType, Consumer<Boolean> resultCallback,
Handler resultCallbackHandler) {
if (taskKey.windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY) {
// We show non-visible docked tasks in Recents, but we always want to launch
// them in the fullscreen stack.
if (options == null) {
options = ActivityOptions.makeBasic();
}
options.setLaunchWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_SECONDARY);
} else if (windowingMode != WINDOWING_MODE_UNDEFINED
|| activityType != ACTIVITY_TYPE_UNDEFINED) {
if (options == null) {
options = ActivityOptions.makeBasic();
}
options.setLaunchWindowingMode(windowingMode);
options.setLaunchActivityType(activityType);
}
final ActivityOptions finalOptions = options;
// Execute this from another thread such that we can do other things (like caching the
// bitmap for the thumbnail) while AM is busy starting our activity.
mBackgroundExecutor.submit(new Runnable() {
@Override
public void run() {
boolean result = false