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 ...
随机推荐
- 高仿bootstrap样式的分页插件
链接:https://pan.baidu.com/s/1jKgn2hK 密码:whwl 不知道是自己的第几个分页插件了,以前写一个丢一个,桌面,U盘,移动硬盘.想用的时候找不到,这次传网上来.大家帮忙 ...
- 获取IP Address
public string GetUserIp() { var visitorsIpAddr = string.Empty; if (System.Web.HttpContext.Current.Re ...
- javascript:Json 和数组的遍历
首先看代码示例var json={a:1,b:2,c:3}; //json var array={1,2,3}; //数组 alert(json.a); //弹出1 或alert(json['a']) ...
- 【OS】NMON的简介和使用
[OS]NMON的简介和使用 目前NMON已开源,以sourceforge为根据地,网址是http://nmon.sourceforge.net. 1. 目的 本文介绍操作系统监控工具Nmon的概念. ...
- PowerShell 并行执行任务
在 PowerShell 中可以轻松的执行后台任务并且让多个后台任务并行执行.本文介绍 PowerShell 中 Job 相关的一些命令,并通过 demo 演示如何在后台同时执行多个任务. Power ...
- Xposed 初尝
1.初次使用xposed,之前直至其名,不闻其用. 2.相关引用配置上图 build.gradle配置,如下: dependencies { compile fileTree(include: ['* ...
- 关于node的基础理论,书上看来的
最近看了一本书,说了一些Node.js的东西,现在来记录一下,让自己记得更牢靠一点. 在书上,是这样介绍的:Node.js模型是源于Ruby的Event Machine 和 Python的Twiste ...
- create-react-app搭建的项目中添加bootstrap
react-bootstrap是一个非常受欢迎的针对react封装过的bootstrap,它本身不包含css,所以也是需要使用bootstrap原生库. 在create-react-app建的项目目录 ...
- WPF项目学习.二
WPF用MVVM的解决记录 版权声明:本文为博主初学经验,未经博主允许不得转载. 一.前言 记录在学习与制作WPF过程中遇到的解决方案. 焦点的控制,键盘事件触发,输入框的数字限制,异步处理,隐藏状 ...
- IDEA的优质使用博客资源
intelliJ idea 使用技巧&方法 IntelliJ IDEA 常用设置讲解 IntelliJ IDEA 详细图解最常用的配置 ,适合刚刚用的新人. IntelliJ IDEA 常见文 ...