问题描述:
1、从Android应用市场下载并安装应用,安装完成后,当前界面下方会出现“打开”按钮,这时候我们点击“打开”,会启动应用,进入到应用的启动页面,然后进入应用的主界面,这个时候我们什么也不做,按Home键返回到桌面,找到应用图标所在区域,点击应用图标,此时我们所期待的现象是重新回到之前我们打开的页面,对吗?然后这个时候你点击桌面上的应用图标打开应用,这个时候你会惊奇的发现应用重新启动了。按返回键你退出应用一次,然后又回到了之前启动的应用页面了。
2、另外,在部分第三方桌面启动app的时候也会有这种情况出现,我测试的时候使用的“米粒桌面“,在全部应用页打开应用,按Home键切到米粒桌面,在米粒桌面的最近使用中打开,会跟上面的结果一样,应用被重启了!
问题重现:
通过上面现象描述,大家应该看懂了问题,可以通过一个具体的实现来重现一下这个问题,首先我安装米粒桌面(非广告,只是我用习惯了,第三方应用市场也是可以),然后安装“哄你”app(也可以尝试其他的app),安装完成后,在米粒桌面的全部应用页面中启动 “哄你”APP,然后按home键切换到米粒桌面的首页,找到最近使用的app列表,打开“哄你”APP,这个时候发现应用会重启,并且退出的时候退出两次才会回到桌面,那么我们来分析一下这是为什么呢?当然,哄你这款软件并不会,因为我做过处理了,所以如果你们想试验的,可以随便挑一款其他APP来测试。
下面是我的调试打印信息:
1、首先从全部应用页面启动哄你APP:
可以看到启动页的Intent信息:
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.kk.sleep/.splash.ui.EntryActivity bnds=[275,1336][545,1606] }
2、按Home键回到桌面,从最近应用中打开哄你APP:
可以看到启动页的OnCrate()再次被调用了! Intent的信息:
Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10600000 pkg=com.kk.sleep cmp=com.kk.sleep/.splash.ui.EntryActivity }
从上面的调试Log中可以看到两次启动的Intent中的Flag不一致!
解决方案:
在启动的Activity的OnCreate方法中加入:
if(!this.isTaskRoot()) {
Log.d(TAG+"_entry","avoid the enrtyActivity re-created");
Intent intent = getIntent();
if(intent !=null) {
String action = intent.getAction();
if(intent.hasCategory(Intent.CATEGORY_LAUNCHER) && Intent.ACTION_MAIN.equals(action)) {
finish();
return;
}
}
}else{
setContentView(R.layout.activity_entry);
init();
}
if(!isTaskRoot()),判断该Activity是不是任务空间的源Activity,如果返回Flase,就是说是被系统重新实例化出来,如果这个Activity是你的Lanucher Activity,这里可以直接Finish关闭页面了。
需要的注意是:
1、如果上面的Activity中实现了finish() 和 onDestroy() 方法,一定要保证这两个方法中不会有对空对象的操作以及注销未注册的广播等类似操作,因为第二次打开应用时,Oncreate()中还没初始化的时候,就会调用finish()方法,及直接触发onDestroy()方法,而这两个函数里面的对象变量都还未进行初始化等操作。
2、finish() 和 onDestroy() 方法中不能有System.exit(0);否则第二次打开应用杀掉进程时也会将第一次打开的应用杀掉。
解决问题的办法很简单,一行代码就搞定,但如果不细心,就难以发现这类烦人的问题。如果大家有什么疑问可以留言,欢迎大家一起交流。