Activity的四种启动模式应用场景

在这金三银四的时间里一个哥们忽然一本正经的问我Activity的启动模式和具体的应用模式;我也一想是啊,平是不太注意结果到了 关键的时刻卡壳了,感觉未雨绸缪一下,做个记录:

一、Activity四种启动模式:

(一)、基本描述
  1. standard:标准模式:如果在mainfest中不设置就默认standard;standard就是新建一个Activity就在栈中新建一个activity实例;
  2. singleTop:栈顶复用模式:与standard相比栈顶复用可以有效减少activity重复创建对资源的消耗,但是这要根据具体情况而定,不能一概而论;
  3. singleTask:栈内单例模式,栈内只有一个activity实例,栈内已存activity实例,在其他activity中start这个activity,Android直接把这个实例上面其他activity实例踢出栈GC掉;
  4. singleInstance :堆内单例:整个手机操作系统里面只有一个实例存在就是内存单例;
(二)、场景设置

Activity的启动模式的应用的设置是和它的开发场景有关系的,在APP中打开新的Activity的基本上分为两种情况:

  1. 目标Activity是本应用中的Activity,即它的启动模式是可以直接在fanifest中配置或者默认为standard,任务栈也可以自己随意设置;
  2. 目标Activity是第三方APP中的Activity这个时候就需要先考虑打开新Activity的是和自己APP放在同一任务栈中还是新的task中【这个是很重要的因为在Android的机制中:同一个任务栈中的activity的生命周期是和这个task相关联的[具体实例见下文]】,然后考虑Activity的启动模式; 所以Android提供了优先级更高的设置方式在Intent.setFlags(int flags),通过这setFlags就可以为打开第三方的APP中Activity设置任务栈和启动模式了,具体设置就自己去看源码了。

二、Activity四种启动模式常见使用场景:

LauchMode Instance
standard mainfest中没有配置就默认标准模式
singleTop 登录页面、WXPayEntryActivity、WXEntryActivity 、推送通知栏
singleTask 程序模块逻辑入口:主页面(Fragment的containerActivity)、WebView页面、扫一扫页面
singleInstance 系统Launcher、锁屏键、来电显示等系统应用

三、实际应用中小插曲

最近的项目就出现了一个由于启动模式导致的问题,先开还是一脸闷还是同事最先想到问题缘由于是做个记录长个教训吧。最近搞的APP是在一个cpu比较low的Android系统的设备上跑的,而且是APP是作为LAUNCHER启动的,并且在APP的一个功能就是点击直接跳转到微信登录LauncherUI页[如果有登录会自动到聊天页面]的,这个听起也是很普通的一个功能。但是还是出了一个小问题。

(一)、问题复现

开机后APP作为launcher启动,然后打开微信LauncherUI加载页【未登录微信】到微信登录页,然后点返回键【系统返回键】不能也退出微信返回到原来我们的launcher的APP中去了,然后Android大法在底部导航栏中查看系统任务【有那些应用在后台】,结果显示一个也没有;这样就是一时间尴尬了退不出微信了;

(二)、问题定位:

1.点击返回键【系统返回键】微信页面没有退出:微信的登录页面Activity拦截了返回键 KeyEvent.KEYCODE_BACK事件【只是将应用隐藏在后台不退出,然后回到桌面】,所以登录Activity没有销毁;
2.系统导航栏查看正在运行的应用为空,实际上是正在运行我们的APP[launcher而且放在在system/app下]和微信的,两个问题缘由:

  1. 我们的APP作为launcher被Android作为系统应用任务栈了所以没有显示;
  2. 微信是在launcherAPP中打开的而且打开代码是并没有设置微信LauncherUI的启动模式和任务栈,Android默认是在同一个任务栈中了,所以在查看任务栈时看不到微信应用,而且由于我们APP是launcher作为系统任务就显示没有应用程序了;
(三)、解决办法

我们的期望是即使不登录微信同样点返回键就可以直接返回到我们APP的页面中;
根据已经点位到问题进行解决一个基本思路是:用户点返回键后杀死微信的Activity,回到我们APP页面中;
具体代码就是

//修改之前
 Intent intent = new Intent();
 intent.setClassName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI");
 context.startActivity(intent);
//修改之后是这样的
 Intent intent = new Intent();
 intent.setClassName("com.tencent.mm", "com.tencent.mm.ui.LauncherUI");
 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 context.startActivity(intent);

其实代码中只是设置新打开微信在新的任务栈中,这样就是及时在微信LauncherUI的页面中拦截了返回键【只是将应用隐藏在后台不退出然后回到桌面】,这样我们APP最为launcher,所以就回到我们APP了。同样这样在在导航栏中查看真正运行任务就可以看到微信了;

(四) 、新的问题

在添加上Intent.FLAG_ACTIVITY_NEW_TASK之后是需要新建一个任务栈打开APP的,虽然是解决了不能返回的问题,但是也引发新的问题:

 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)

1.用户点返回键后微信并没有退出:在界面上看到是回到桌面APP中了,其实微信并没有退出任然在后台运行;这个问题其实普遍存在,而且开发者基本上都是对用户采取理性欺骗【或者隐瞒】,现实中用户也是都已经接受;

2.点击跳转到微信明显卡顿:以前打开新的APP是在一个任务栈中的,打开新APP页面和在同一APP页面跳转感觉基本上是一瞬间的,用户感觉不到是在APP之间跳转的,设置Intent.FLAG_ACTIVITY_NEW_TASK之后是需要新建一个任务栈打开APP的,点击后有明显的停顿【CPU越差劲越明显】用户体验明显变差了。

猜你喜欢

转载自blog.csdn.net/black_bird_cn/article/details/79764794