Android启动模式选用存在的问题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

当前迭代的项目Muza在1.48版本中加入一对一视频通话的功能,场景与微信视频通话类似,在私信界面发起方发起进入视频界面,接收方收到视频邀请进入视频,接收方接受后开始通话。功能的搭建基于声网的SDK,但在开发测试环节出现了启动模式相关的问题。

出现的问题

对于双方视屏交互界面的Activity,考虑到要做退出小窗悬浮,以及视屏功能对于整个APP来说同一时刻唯一性,所以选用了单列启动模式(singleInstance),此种模式让页面独立于应用默认的Task,自己独占一个Task.
Task是啥?开发时间越长,有些问题就越思极恐,因为会发现简单的问题理解错了。任务栈,每个应用都会有自己默认的任务栈,来管理应用内部的Activity出入即显示,当我们把手机切到任务列表的时候看到的就是对应最近我们打开APP的Task.Task分为前台和后台,通过Home键或者最近列表键可以让Task从前台变为后台,后台中的Activity都处于暂停的状态。测试环节中发现,从视频页按Home键退回桌面或者进入任务列表,再次启动APP(或者从任务列表进入)会发现视频交互页面还在,但如果按返回键就会退出APP,而正常的期望场景是退回应用原先调用视频的界面。
任务列表

Android中的四种启动模式:默认(standard)、栈顶复用(singleTop)、栈内复用(singleTask)、单列模式(singleInstance),对大多数的页面来说都要选用默认的模式启动,像登录页面或者通知消息点击进入的详情页面可以选用singleTop,一般像主界面会选用singTask.单列模式则对于整个系统来说是唯一的,像闹铃界面。activity是重量级组件,意味着可以在不同的应用间调用,而涉及到不同应用的调用这种场景,而对于singleTask和singleInstance来说这里头还是有点东西的。
singleTask:Activity 是一个可以跨进程、跨应用的组件。当你在 A App 里打开 B App 的 Activity 的时候,这个 Activity 会直接被放进 A 的 Task 里,而对于 B 的 Task,是没有任何影响的。在单个Task中的体现是没有实例的话会创建,有的话干掉上部Activity,然后置于栈顶走onNewIntent。这里列举一个singleTask在多个应用或者Task间场景:前台任务栈A、B(B在栈顶),后台任务栈C、D(都为singleTask模式D在栈顶),第一种:B启动D,对于前台任务栈会变成ABCD,第二种:B启动C,前台任务栈变成ABC。总结下就是,被singleTask修饰的页面在被调用时会在自己的栈内创建,如果有就把自己放到栈顶,然后把整个Task放到调用的Task上。这种属于Task间的切换,在切换时会有应用间切换的动画而不是普通Ac切换的动画。
再说singleInstance,和上面的有啥区别吗?singTask是保证了一个Task中只有一个Activity同时只有一个Task中有,singleInstance和singTask类似的行为但所在的Task只能有它自己不能有别的。
做一个小测试,三个Activity Activity注册文件
123按顺序跳转,1到2是一个切换Task的过程,会明显的看到切换动画不同是应用间的动画,2到3就是普通的跳转,从3按返回键会怎样?会返回到1,1再返回呢?会到2,再返回呢?退出回到桌面了。这么看的话就是说,2单独一个Task,13在一个Task,所以3挂了找1,1挂了这个找下面的栈,这个栈还一个2,2没了退出应用。
再试一下开头说的问题:12跳转,第一种:跳到2的时候切换到任务列表,再回来,再从任务列表点击回来出现的还是2,再按下返回键就推出了。第二种:跳到2的时候按home键,从桌面Icon启动APP,2就没了,出来的是1。而对应的正确的姿势是:任务列表点进来我按返回回到1,home退出通过icon进来显示2,2返回退出还是显示1。
还有就是为什么最近列表里不会同时有singleInstance的Task和应用的Task呢?因为同一个 taskAffinity 可以被创建出多个 Task,但它们最多只能有一个显示在最近任务列表。
上面这个2其实就是视频交互的界面,why?看了这么多文章,再试一遍,也就大概了解了。按最近任务键的时候前台任务就已经被转换为后台任务了,1自身的应用Task和2单独的Task都应该被转换了,而从任务列表再次进入的时候显示的是2的Task这个时候1的task还是后台状态,再退出就到桌面了。而按home键,再次从桌面启动,会走正经的流程,去找应用的Task,所以默认的启动了1。可能说的不对但感觉差不多是这个意思。

二、关于解决的方法

所有的解决方法都不会唯一,只有合理或者更合理。关于换回直接退出APP的解决方法

 private void moveAppToFront() {
        ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningTaskInfo> recentList = am.getRunningTasks(30);
        recentList.remove(0); //去掉当前 Activity
        for (ActivityManager.RunningTaskInfo info : recentList) {
            if (info.topActivity.getPackageName().equals(getPackageName())) {
                am.moveTaskToFront(info.id, 0);
                return;
            }
        }
    }

找到当前应用的task,并启动task的栈顶activity,达到程序切换到前台。关于从桌面点击icon进入页面显示不对的情况,参考网上大多数的解决方案,设置一个Activity变量,用于保存页面状态,而对于所有的其他Activity在执行onResume的时候都检查一下标记,如果页面存在就跳转,registerActivityLifecycleCallbacks中做监听也可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值