请选择 进入手机版 | 继续访问电脑版

ActivityManagerService对于Task的管理

[复制链接]
为你演绎 发表于 2021-1-1 18:29:27 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题
在Ams中Activity的容器是Task, task的容器是stack, 所以我们先来看下stack是如何管理Task的
  1. final class ActivityStack {    /**     * The back history of all previous (and possibly still     * running) activities.  It contains #TaskRecord objects.     */    private ArrayList mTaskHistory = new ArrayList();}
复制代码
再来看下TaskRecord
  1. final class TaskRecord {    /** Indication of what to run next when task exits. Use ActivityRecord types.     * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the     * task stack. */    private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;}    static final int APPLICATION_ACTIVITY_TYPE = 0;    static final int HOME_ACTIVITY_TYPE = 1;    static final int RECENTS_ACTIVITY_TYPE = 2;
复制代码
ActivityStack使用mTaskHistory来管理多个Task,Task的mTaskToReturnTo代表该Task上最后一个Activity销毁后返回的Task范例,分别是:


  • APPLICATION_ACTIVITY_TYPE 返回到另外一个平凡应用的Task。
  • HOME_ACTIVITY_TYPE 表示返回到桌面。
  • RECENTS_ACTIVITY_TYPE 表示返回到最近任务。
通常由于我们一个Activity启动了一个新的Task,那么新Task返回后就应该返回到Task对应的Activity上。 但是思量如下两种情况:

  • 假如用户按Home键,然后从某个应用图标进入某个Task,则Task退出后应返回到桌面。
  • 假如用户按最近任务键,切入某个Task, 则该Task退出后也应该返回到桌面。
所以通过最近任务和桌面进入Task会粉碎掉原来的Task返回链路。Task.mTaskToReturnTo都会变为HOME_ACTIVITY_TYPE大概RECENTS_ACTIVITY_TYPE。
Ams怎么管理Stack呢? 从6.0开始Android支持多stack,也就是分屏。Android使用stack管理Activity的回退路径,使用stack管理屏幕上的多个窗口(多个回退路径)。
  1. class ActivityDisplay {        /** All of the stacks on this display. Order matters, topmost stack is in front of all other         * stacks, bottommost behind. Accessed directly by ActivityManager package classes */        final ArrayList mStacks = new ArrayList();}
复制代码
每个Display下面可以有多个ActivityStack。外界如何控制stack的大小位置? 通过ActivityContainer
  1. class ActivityContainer extends android.app.IActivityContainer.Stub {        @Override        public int getStackId() {            synchronized (mService) {                return mStackId;            }        }        @Override        public boolean injectEvent(InputEvent event) {            final long origId = Binder.clearCallingIdentity();            try {                synchronized (mService) {                    if (mActivityDisplay != null) {                        return mInputManagerInternal.injectInputEvent(event,                                mActivityDisplay.mDisplayId,                                InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);                    }                }                return false;            } finally {                Binder.restoreCallingIdentity(origId);            }        }     ......        @Override        public final int startActivity(Intent intent) {            mService.enforceNotIsolatedCaller("ActivityContainer.startActivity");            final int userId = mService.handleIncomingUser(Binder.getCallingPid(),                    Binder.getCallingUid(), mCurrentUser, false,                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);            // TODO: Switch to user app stacks here.            String mimeType = intent.getType();            final Uri data = intent.getData();            if (mimeType == null && data != null && "content".equals(data.getScheme())) {                mimeType = mService.getProviderMimeType(data, userId);            }            checkEmbeddedAllowedInner(userId, intent, mimeType);            intent.addFlags(FORCE_NEW_TASK_FLAGS);            return startActivityMayWait(null, -1, null, intent, mimeType, null, null, null, null,                    0, 0, null, null, null, null, false, userId, this, null);        }        @Override        public final int startActivityIntentSender(IIntentSender intentSender)                throws TransactionTooLargeException {            mService.enforceNotIsolatedCaller("ActivityContainer.startActivityIntentSender");            if (!(intentSender instanceof PendingIntentRecord)) {                throw new IllegalArgumentException("Bad PendingIntent object");            }            final int userId = mService.handleIncomingUser(Binder.getCallingPid(),                    Binder.getCallingUid(), mCurrentUser, false,                    ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);            final PendingIntentRecord pendingIntent = (PendingIntentRecord) intentSender;            checkEmbeddedAllowedInner(userId, pendingIntent.key.requestIntent,                    pendingIntent.key.requestResolvedType);            return pendingIntent.sendInner(0, null, null, null, null, null, null, 0,                    FORCE_NEW_TASK_FLAGS, FORCE_NEW_TASK_FLAGS, null, this);        }        @Override        public void setSurface(Surface surface, int width, int height, int density) {            mService.enforceNotIsolatedCaller("ActivityContainer.attachToSurface");        }        ......}
复制代码
ActivityContainer是一个Binder服务,客户端拿到对应的Binder署理就可以通过ActivityContainer在Task上创建Activity了。另外ActivityManagerService的resize函数可以设置ActivityStack的大小和位置,这也是分屏实现的根本。
  1.     @Override    public void resizeTask(int taskId, Rect bounds) {        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,                "resizeTask()");        long ident = Binder.clearCallingIdentity();        try {            synchronized (this) {                TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);                if (task == null) {                    Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");                    return;                }                mStackSupervisor.resizeTaskLocked(task, bounds);            }        } finally {            Binder.restoreCallingIdentity(ident);        }    }
复制代码
在默认不分屏的情况下Android有两个Satck,分别对应最近任务和桌面所在的stack(HomeStack),以及平凡应用所在的Stack。当全屏应用启动后,应用ActivityStack会覆盖在HomeStack上。当遇到Task.mTaskToReturnTo的Task清空后,由于平凡应用的Activity都不可见则HomeStack就显示了出来。

来源:https://blog.csdn.net/woai110120130/article/details/112055548
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


专注素材教程免费分享
全国免费热线电话

18768367769

周一至周日9:00-23:00

反馈建议

27428564@qq.com 在线QQ咨询

扫描二维码关注我们

Powered by Discuz! X3.4© 2001-2013 Comsenz Inc.( 蜀ICP备2021001884号-1 )