Android Bug分析系列:第三方平台安装app启动后,home键回到桌面后点击app启动时会再次启动入口类bug的原因剖析

最近公司测试测出来这么一个问题

具体表现是:

1,用QQ将我们自己的apk包从电脑端传送到手机端,点击安装,安装成功后点击QQ浏览器的打开按钮(这时候的逻辑应该是触发闪屏页,然后finish掉闪屏页,接着跳转到主页Activity(主页Activity是SignleTask设计模式的))

2,然后点击Home键,回到桌面

3,再在桌面上点击app的icon,原谅耿直的我们都是觉得应该直接回到【主页Activity】,但是结果却是又一次触发 【闪屏页Activity】,亮瞎了24K钛合金狗眼的我们觉得这玩法不对吧?

4,但是在QQ安装器安装成功后,不点击QQ浏览器页面的打开按钮,而是回到桌面点击app的icon,接着执行2和3步骤,是不会有问题的

4,好吧,只能自己分析原因解决问题了

现象分析

上面两种操作方式的不同点在于也就是启动App的入口不一样。一者是平常的桌面Icon图标启动,一者是QQ安装这类第三方平台启动,我们都知道,桌面启动的话也是通过startActivity这个api通过特定的Intent向ActivityManageService发起启动任务,所以可以推测出的是QQ安装启动这类方式也是通过Intent启动对应的App,所以,可以肯定的是,通过QQ安装启动这类方式和通过桌面点击app的icon图标方式并不完全一致

背景知识

1,Activity的Task管理

我们都知道,当一个具有singleTask启动模式的Activity请求启动后,比如Activity A,系统首先会寻找是否存在A想要的任务栈,如果不存在,则就重新创建一个任务栈,然后创建A的实例把A放到任务栈中,如果存在A所需的任务栈,这时候要看A在栈中是否有实例存在,如果有实例存在,那么系统就会把A调到栈顶并调用它的onNewIntent,如果实例不存在,就创建A的实例并把A压入栈中,那什么是A想要的任务栈呢,这就涉及到Activity的TaskAffinity,可以翻译为任务相关性,这个参数标示了一个Activity所需要的任务栈的名字,默认情况下,所有Activity所需的任务栈的名字为应用的包名。当然,我们可以为每个Activity都单独制定TaskAffinity,这个属性值必须不能和包名相同,否则就相当于没有指定,需要指出的是TaskAffinity主要和singleTask启动模式配对使用,在其他情况下并没有意义。

一般来说,Android系统中App的启动与切换依赖于Activity的Task管理,下面简单分析一下不同应用之间切换时候相关Task的变化,根据上面的分析,一个应用中可能有多个Task,一个Task中也有可能有多个Activity,为了简单起见,下面假设A、B、C三个应用都是单Task的

桌面程序App(A):【TaskA】 ---- 存在Activity有【A1】 ----  其栈的结构为 A1

应用程序B:【TaskB】 ---- 存在Activity有【B1】【B2】 ---- 其栈的结构为 B1B2

应用程序C: 【TaskC】 ---- 存在Activity有【C1】【C2】 ---- 其栈的结构为 C1C2

依次进行下面的操作

a、那么我们进入桌面时:Task之间的结构是 A1 ---- 也就是只有一个【TaskA】栈(桌面Task),并且位于最前端(这里表现为最后添加的末端)

b、然后我们点击应用程序B的图标,启动B :Task之间的结构是 A1B1B2  ---- 添加了一个【TaskB】,而且【TaskB】也是位于最前端,现在显示的是【TaskB】的B2的Activity的界面

c、接着点击home键: Android对于home做了特殊默认处理,就是会把桌面Task挪到所以Task最前端,Task结构应该变成  B1B2A1 ---- 【TaskA】挪到队列最前端,现在显示的是【TaskA】的A1的Activity的界面,也就是桌面

d、我们再在桌面点击应用程序C的图标,启动C : Task之间的结构变成 B1B2A1C1C2 ---- 添加了一个【TaskC】,而且【TaskC】也是位于最前端,现在显示的是【TaskC】的C2的Activity的界面

好了,说了这么多,下面接着分析bug

原理剖析

 从此我们可以知道QQ安装器其实也就是使用Intent来启动其刚刚安装的那个App,但是问题所在的是:他们的启动Intent并没有跟桌面的启动Intent完全一致!

而从柯元旦所著的《android内核剖析》一书中有记录如下规则:

每次启动Intent导致新创建Task的时候,该Task会记录导致其创建的Intent;而如果后续需要有一个新的与创建Intent完全一致(完全一致定位为:启动类,action、category等等全部一样,不可多项也不可缺少),那么该Intent并不会触发Activity的新建启动,而只会将已经存在的对应Task移到前台;这也就是为什么桌面会在再次点击图标时将后台任务挪到前台而不是重新启动App的实现。

我们将桌面的Task记为【TaskL】,QQ安装器的Task记为【TaskQ】,我们应用的Task记为【TaskA】,那么分析如下:(L1是单纯的桌面)

打开QQ: L1Q1Q2 ---- Q2是安装完毕后询问是否启动对应程序的Activity

点击打开: L1Q1Q2A2 ---- A1是入口闪屏页,A2是主页Activity,启动后A1业务逻辑应该finish掉,所以从【TaskA】中挪去

返回桌面: Q1Q2A2L1 ---- 回到桌面页,也就是L1前置

点击A的图标: Q1Q2L1A2A1 -> Q1Q2L1A2A1 ---- 找到【TaskA】,挪到前台,由于比对Intent并不是完全一致,所以该请求是新启动Activity,那么把A1添加到对应的【TaskA】中,然后A1所再一次触发启动主页,但是主页是singleTask模式,所以又回到了上次对应的A2主页,所以现象为再一次出现闪屏页,然后回到原先的主页界面。

解决思路

1、让腾讯那些第三方平台修正其启动Intent的设置,使其与原声桌面启动Intent保持完全一致。(PS:基本不可能)

2、自身业务代码规避,我们可以知道,如果是多余的闪屏页入口Activity的话,其基本不可能位于Task的根部,而如果正常启动的话,闪屏页入口Activity必定在多对应的Task的根部位置,那么我们可以从这个地方对于这个bug进行规避,方法就是在闪屏页入口Activity的onCreate代码加入如下一段代码:

// 避免从桌面启动程序后,会重新实例化入口类的activity

if(!this.isTaskRoot()) {

    Intent intent = getIntent();

    if(intent !=null) {

        String action = intent.getAction();

        if(intent.hasCategory(Intent.CATEGORY_LAUNCHER) && Intent.ACTION_MAIN.equals(action)) {

            finish();

            return;

        }

    }

}

 问题解决!

https://www.cnblogs.com/net168/p/5722752.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容