Android: SingleInstance 填坑 —— 返回上一级Activity

因为一个多任务的需求,所以想到了使用 SingleInstance 方式启动多任务容器 Activity,保证一定情况内 Activity 不被销毁,可以随时切换回来操作。

基于面向百度编程可知 SingleInstance 会另开一个返回栈(Task)来启动该 Activity,但首先有两个问题需要解决:

1. 如何从SingleInstance 返回到上一个 Activity
2. ActivityResult的实现

这篇文章中我们先来解决第一个问题:

(1) 直接调用 moveTaskToBack(boolean nonRoot) 方法

    @Override
    public void onBackPressed() {
        moveTaskToBack(true);
    }

这个方法使用时看似方便,但是一旦用户通过概览屏幕(或者叫最新动态屏幕、最近任务列表或最近使用的应用)回到这个 SingleInstance,再点击返回按钮隐藏任务栈就会导致app直接返回到主页面。这里我们就需要想办法回到上一个 Activity 的返回栈。

(2) 通过遍历返回栈回到上一个 Activity

    @Override
    public void onBackPressed() {
        moveTaskToBack(true);
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        assert manager != null;
        List taskInfoList = manager.getRunningTasks(30);
        for (ActivityManager.RunningTaskInfo task : taskInfoList) {
            if (task.topActivity.getPackageName().equals(getPackageName()) && task.id != getTaskId()) {
                manager.moveTaskToFront(task.id, 0);
                break;
            }
        }
    }

这种方法能够较好地解决返回问题,moveTaskToFront(int taskId, @MoveTaskFlags int flags)需要 REORDER_TASKS 权限。这里值得注意的是 ActivityManager#getRunningTasks(int maxNum) 这个方法在 Android 5.0 被弃用,API >= 21 时只能获取到当前APP的返回栈。

(3) 直接向 SingleInstance Activity 传递 TaskId

在 Intnet 跳转时直接传入该 Activity 所在的 TaskId

    public void show(Context context) {
        Intent intent = new Intent(context, MultiTaskActivity.class);
        intent.putExtra(MultiTaskConstant.INTENT_EXTRA_TASK_ID, ((Activity)context).getTaskId());
        context.startActivity(intent);
    }

返回时直接通过 TaskId 回到上一个栈。

    @Override
    public void onBackPressed() {
        moveTaskToBack(true);
        ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        assert manager != null;
        int taskId = getIntent().getIntExtra(MultiTaskConstant.INTENT_EXTRA_TASK_ID, Integer.MIN_VALUE);
        if (taskId > 0) {
            manager.moveTaskToFront(taskId, 0);
        }
    }

参考资料:

Android Developer: 概览屏幕
Android Developer: 任务和返回栈

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注