Android应用Home键后Launcher重复启动问题
通过系统方式(系统安装器)安装应用,点击“打开”按钮,进入应用主界面,按home键后,点击应用图标进入,应用会出现重新启动。当完全退出应用后,再通过启动图标进入应用,便不会出现重复启动问题。目前测试大部分Android机型均会出现此类问题。
重现方式
- 系统安装器安装APK(含覆盖安装),成功后点击“打开”按钮,进入应用。
- 应用正常启动为AAActivity,然后进入主页面MainActivity,此时进入二级页面A或三级页面B。
- 按home键,将程序置于后台。
- 在launcher上打开APP。
- 程序重新启动,先AAActivity后MainActivity。
定位了问题重现方式,发现只是系统安装器安装后,会出现重复启动问题。因此检查安装器打开应用与launcher打开应用的不同,为此在首次启动页面AAActivity打印action,category,flags,TaskId,Pid信息。重复上述过程。
1.当通过安装器打开APP时,log信息如下:
AAActivity:
getAction:android.intent.action.MAIN
getCategories:android.intent.category.LAUNCHER
getFlags:Intent.FLAG_ACTIVITY_NEW_TASK
TaskId:308,Pid:5445
2.按home键,launcher上打开APP,log信息如下:
AAActivity:
getAction:android.intent.action.MAIN
getCategories:android.intent.category.LAUNCHER
getFlags:Intent.FLAG_ACTIVITY_NEW_TASK,Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
TaskId:308,Pid:5445
3.多次重复按home键,重复打开APP,log信息与2中相同,因此可以判断此时新建的AAActivity是压入之前的任务栈中。
4.完全退出应用程序,即销毁原有任务栈,launcher上打开APP,log信息如下:
AAActivity:
getAction:android.intent.action.MAIN
getCategories:android.intent.category.LAUNCHER
getFlags:Intent.FLAG_ACTIVITY_NEW_TASK,Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
TaskId:309,Pid:7150
结论
通过以上log信息可以确定以下结论:
1)AAActivity用安装器打开应用flag为FLAG_ACTIVITY_NEW_TASK,launcher打开应用比系统安装器多了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED。
2)用FLAG_ACTIVITY_NEW_TASK创建的任务栈,再用FLAG_ACTIVITY_RESET_TASK_IF_NEEDED(launcher方式)打开,会在AAActivity多了FLAG_ACTIVITY_BROUGHT_TO_FRONT。
3)异常重复启动过程中,新建AAActivity的TaskId与Pid一致,可确定还是在原有任务栈中创建Activity,打开多次MainActivity(standard启动模式)会在原有任务栈中叠加。
解决方法
在启动页(AAActivity)中通过isTaskRoot(Return whether this activity is the root of a task. The root is the first activity in a task.)方法来进行判断:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isTaskRoot()) {
finish();
return;
}
}
判断逻辑为:判断启动页是否为当前任务栈的根Activity,如果不是根Activity则finish掉。语意上来讲,一个任务栈的根Activity应是启动页,这样也符合正常的应用场景;如果不是根Activity,那么说明出现了异常启动,应当将该启动页销毁掉,显示原有任务栈。
而此判断方法也是基于以上结论(3)来解决的,还有一种判断方式是基于结论(2),在AAActivity中判断是否含有FLAG_ACTIVITY_BROUGHT_TO_FRONT标志:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ((getIntent().getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
finish();
return;
}
}
先来看下API中对FLAG_ACTIVITY_BROUGHT_TO_FRONT标志位的解释:
/**
* This flag is not normally set by application code, but set for you by
* the system as described in the
* {@link android.R.styleable#AndroidManifestActivity_launchMode
* launchMode} documentation for the singleTask mode.
*/
public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 0x00400000;
此标志位是singleTask 启动模式下,由系统进行设定的。但在测试过程中的AAActivity为standard启动模式,也会添加该标志位?关于这一点官方也没有一个明确的关于该标志位的说明。因FLAG_ACTIVITY_BROUGHT_TO_FRONT使用的未知性,以及AAActivity启动模式特殊性,最终还是选取用isTaskRoot()来进行判断。
1.AAActivity中如果实现了finish() 和 onDestroy()方法,要保证这两个方法无空对象操作以及注销未注册的Service等类似操作。因为二次打开AAActivity在onCreate()方法中便finish()掉,可能涉及一些变量未初始化操作等。
2.finish() 和 onDestroy()方法中不能调用System.exit(0);否则二次打开AAActivity杀掉进程时也会将之前任务栈活动杀掉。
3.如果MainActivity为singleTask 启动模式(也符合一般应用场景),那么就会出现异常启动情况下新AAActivity打开原MainActivity并将MainActivity之上的其他Activity clear掉,因此展现给用户的就是再次点击launcher,会先进AAActivity,再进入保留原有活动的MainActivity。
4.launcher打开应用比系统安装器多了FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,证明添加了该标志位的栈,不会存在重复启动问题,这也符合API中该标志位如果存在一个已经存在的栈则会复用原栈的说明。
Android应用Home键后Launcher重复启动问题的更多相关文章
- Android使用Home键后应用程序重启的问题
正常情况应该是在点击 home 按键后,程序在后台暂停运行,点击 后退键 才会退出应用的,但是今天遇到个问题,点击 home 键后,重新再打开应用却每次都返回应用启动页面,有些莫名其妙,一番googl ...
- [Android]从Launcher开始启动App流程源码分析
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5017056.html 从Launcher开始启动App流程源码 ...
- Android按下home键后重新打开app进入主activity的问题
问题阐述: 当我们写一款App的时候,势必会有这种情况:用户已经进行了多级的操作,现返回栈中已存在多个activity,那么这个时候我们想回到最初的activity难道要一层层的返回吗,对用户来说 无 ...
- Android实现点击通知栏后,先启动应用再打开目标Activity ,极光推送等推送的也可以参考一下(转)
我因为项目中集成了极光推送,推送的通知栏点开需要确定进入哪个界面就参考了这边文章,感谢作者的无私. 标签: 情况简述 在开发Android app的过程中,遇到这样一个需求:app中启动一个Servi ...
- Android更改桌面应用程序launcher的两种方式
http://blog.csdn.net/mdx20072419/article/details/9632779/ launcher,也就是android的桌面应用程序.下图是我正在使用的魅族手机的l ...
- 【转】Android Service被关闭后自动重启,解决被异常kill 服务
http://www.kaifajie.cn/android/10182-2.html 每次调用startService(Intent)的时候,都会调用该Service对象的onStartComman ...
- 我的Android进阶之旅------>关于使用Android Studio替换App的launcher图标之后仍然显示默认的ic_launcher图标的解决方法
前言 最近做了一个App,之前开发该App的时候一直以来都是默认的launcher图标启动的, 今天美工换了一个App的launcher 图标,因此在Android Studio中将默认的lanche ...
- 【Maven】Eclipse安装Maven插件后导致Eclipse启动出错
本文纯属复制粘贴:具体请参照原文: Eclipse安装Maven插件后,Eclipse启动问题:Maven Integration for Eclipse JDK Warning. 解决方法: 1. ...
- Android四大组件及activity的四大启动模式
Android四大组件 1. 广播接收者的两种类型: (1)系统广播接收者,就是继承BroadcastReceiver这个类,然后还要在清单文件中注册,注册之后给他一个action.当系统发生了这个a ...
随机推荐
- [DeeplearningAI笔记]ML strategy_1_3可避免误差与改善模型方法
机器学习策略 ML strategy 觉得有用的话,欢迎一起讨论相互学习~Follow Me 1.8 为什么是人的表现 今天,机器学习算法可以与人类水平的表现性能竞争,因为它们在很多应用程序中更有生产 ...
- hexo搭建博客上传至github
准备工作 ssh key 要先申请好,并且添加至github的ssh库中 安装插件 hexo-deployer-git npm install hexo-deployer-git --save 配置 ...
- 2017年总结的前端文章——CSS盒模型详解
CSS的盒模型是CSS的基础,同时也是难点,这个问题经常在面试中会被问到,属于经典问题了.很多博客里讲得也很模糊不清,于是,我在这里重新整理一下. 可以认为每个html标签都是一个方块,然后这个方块又 ...
- SEO页面优化以及如何对单页面应用进行SEO优化
一.简介 1.何为SEO? SEO(search engine optimization),翻译为搜索引擎优化,是利用搜索引擎的搜索规则来提高在相关搜索引擎的排名以及访问量的方式. 2.目的 为了获取 ...
- Linux系统zookeeper环境搭建(单机、伪分布式、分布式)
本人现在对zookeeper的环境搭建做一个总结,一般zookeeper的安装部署可以有三种模式,单机模式.伪分布式和分布式,这三种模式在什么时候应用具体看大家的使用场景,如果你只有一台机器且只是想自 ...
- BZOJ 3697: 采药人的路径 [点分治] [我想上化学课]
传送门 题意: 路径有$-1,1$两种权值,求有多少路径满足权值和为$0$且有一个点将路径分成权值和为$0$的两段 第四节课本来想去上化学,然后快上课了这道题还没调出来.....可恶我想上化学 昨天两 ...
- [偏序关系与CDQ分治]【学习笔记】
组合数学真是太棒了 $CDQ$真是太棒了(雾 参考资料: 1.<组合数学> 2.论文 课件 很容易查到 3.sro __stdcall 偏序关系 关系: 集合$X$上的关系是$X$与$X$ ...
- 2018/2/14 设计模式学习笔记(一) 自己实现ArrayList,LinkedList和Iterator,以及在此过程中对于面向对象,面向接口,还有抽象类的一些思考感悟
因为本人目前为止学习编程不过七个月,所以后面的感悟对于一些大神来说可能嗤之以鼻,但对于一些刚刚入门的萌新来说在理解面向对象的思想上,以及抽象类和接口应该怎么设计等方面应该还是会有所帮助的 首先我们定义 ...
- 深入JavaScript类型判定
JavaScript的数据类型 基本区分方法 ECMAScript标准定义了7种数据类型 6 种 基本类型: Boolean,两种取值:true和false Null,一种取值:null Undefi ...
- python数据分析工具包(1)——Numpy(一)
在本科阶段,我们常用的科学计算工具是MATLAB.下面介绍python的一个非常好用而且功能强大的科学计算库--Numpy. a powerful N-dimensional array object ...