Android starActivity的一些研究

2019-03-19  本文已影响0人  水天滑稽天照八野滑稽石

前言

总所周知,Activity有四种启动方式,但很少谈到它还有多种flag帮帮助我们来设定不同的Activity启动方式,这里我们就来踩一踩starActivity的那些坑

任务栈

要了解Activity的启动方式那些事,首先要先了解下任务栈

任务栈的缺陷

启动模式

启动模式就是为了解决任务栈的缺点而提出来的。

启动模式(launchMode)在多个Activity跳转的过程中扮演着重要的角色,它可以决定是否生成新的Activity实例,是否重用已存在的Activity实例,是否和其他Activity实例公用一个task里。这里简单介绍一下task的概念,task是一个具有栈结构的对象,一个task可以管理多个Activity,启动一个应用,也就创建一个与之对应的task。

正文

前三种启动模式相信大家已经很熟悉了,这篇博客相信很多人也看过,但还有很多情况没有提及到,这里就做一下补充

Q:如何如何查看有多少个任务栈和任务栈里有多少个Activity及分别是那些Activity?

使用adb,里面有一条指令可以查看手机中的任务栈

  1. 打开SDK Manager,查看自己的SDK安装目录
  2. SDK安装目录下有一个platform-tools目录,里面就是你adb的安装目录
  3. 打开cmd,cd 到adb目录下,使用adb shell dumpsys activity activities查看任务栈

可以看到在栈ID为80的栈下有4个Activity,栈顶是e985b73这个Activity

singleInstance

Q:singleInstance是开启一个新的任务栈,那么把Activity设定为singleInstance重复启动会是什么情况?

Activity A 是standrad启动模式,Activity B是singleInstance启动模式,A ->B之后,B重复启动B会发生什么?


看来singleInstance启动之后在再启动自己不会创建新的实例

那么继续,再加一个Activity C,standrad启动模式,A->B->C->B 会发生什么事?


gif演示的比较快,不方便看,可以看下这个图



那回退呢?是怎么样的




上面的是A->B-C->B->C启动,如果是A->B->C->B启动的话,回退是这个样子的

因为通过singleInstance启动的Activity会单独的压入一个新的栈中,有且只有一个,又居于栈内复用的特性,所以不会重复创建新的实例

Q:使用singleInstance模式的Activity通过startActivityForResult会发生什么事

Activity A 是standard,Activity B是singleInstance启动模式,从B返回A会弹出一个吐司显示valus


可以看到,singleInstance失效了,它还是在栈77里面,并没有开启新的栈
我试验了多次,发现了如下规则,具体原因是Android底层做的优化,但为什么这样做是不知道的
Android 5.0 之前:
A通过startActivityForResult启动B会在一个新的任务栈中,但onActivityResult是拿不到返回的intent的
Android 5.0之后:
A通过startActivityForResult启动B会在同一个任务栈中,在通过startActivity启动C(C是standard),C会在新的任务栈中,如果还是startActivityForResult,则依旧在同一个任务栈中,所以onActivityResult方法也会正确触发。
这一规则同样适用于singleTask设置不同的taskAffinity来新的栈

Q:A、B在不同的任务栈,通过A启动B后,在从B回到A,如何获取到B的数据?

我们知道正常情况下是可以通过startActivityForResult获取到传回的数据,但是在不同任务栈中会失效,startActivityForResult的源码也有注释

   /**
     * <p>Note that this method should only be used with Intent protocols
     * that are defined to return a result.  In other protocols (such as
     * {@link Intent#ACTION_MAIN} or {@link Intent#ACTION_VIEW}), you may
     * not get the result when you expect.  For example, if the activity you
     * are launching uses {@link Intent#FLAG_ACTIVITY_NEW_TASK}, it will not
     * run in your task and thus you will immediately receive a cancel result.
  */

singleTop和singleTask复用自己的时候都会调用onNewIntent,可以在这里获取到intent来取出从B传回的值

Activity的常用Flag

上一篇 下一篇

猜你喜欢

热点阅读