最近系统同事分析monkey anr问题时,有一次发现com.android.phone中有10个RadioInfo实例。让分析RadioInfo是否有溢出。

查看代码,RadioInfo是packages/apps/settings目录下的一个activity。

即说明RadioInfo activity有10个实例。以前没有关注过一个activity有多个实例的情况。这次就学习一下。

为何settings下的RadioInfo属于com.android.phone进程呢?

下面的配置中android:process=“com.android.phone”决定了RadioInfo activity在com.android.phone进程下拉起。

android应用Actitvity启动多个实例方式

如何用am应用启动RadioInfo?

由于RadioInfo intent-filter 的action是android.intent.action.MAIN。可以通过-a参数拉起。

  [-a <ACTION>] 

操作如下,没有报错。但是手机界面弹出选择框,有很多应用供选择。RadioInfo是其中之一。因为基本所有应用都有一个Activity页面的intent-filter 的action是android.intent.action.MAIN。(只有这样应用在桌面点击时才能决定拉起哪个Activity。)

android应用Actitvity启动多个实例方式

如果要直接拉起RadioInfo,就要用-n参数。如下:

android应用Actitvity启动多个实例方式

执行这三个命令后,发现有两个RadioInfo页面,说明此Activity有两个实例启动。为何有两个呢?注意,如果将-f 0x18000000去掉,如下三个命令,则只有一个RadioInfo实例启动。

android应用Actitvity启动多个实例方式

这就要看-f 0x18000000是何含义了。参见Intent.java,关键在于0x8000000 flag.

android应用Actitvity启动多个实例方式


当为18000000,即FLAG_ACITIVITY_NEW_TASK和FLAG_ACTIVITY_MULTIPLE_TASK时,允许拉起同一个Activity多个实例。但条件是传入的Intent和之前实例的intent不同。在上面截图中,三个intent,一个act为aaa,第二个和第三个act为bbb。所以第一次,第二次都拉起新的Activity,但是第三次由于和第二个intent相同,就不会拉起新的Activity。

有兴趣的同学也可以试试0x8080000,即FLAG_ACITIVITY_NEW_DOCUMENT和FLAG_ACTIVITY_MULTIPLE_TASK.其他不变,即三个intent,一个act为aaa,第二个和第三个act为bbb。此时会拉起3个RadioInfo,不管intent内容是否相同。

但是这也是和Activity的配置有关。如果将RadioInfo的配置修改,添加一个singleTask属性,

android应用Actitvity启动多个实例方式

那么再去尝试上面的命令就会有warning报错,如下图。因为singleTask属性存在,无论intent的参数如何,只允许一个Activity实例。

android应用Actitvity启动多个实例方式

am 源码

入口:

android应用Actitvity启动多个实例方式

android应用Actitvity启动多个实例方式

接着到ActivityManagerService.java文件中onShellCommand()处理:

android应用Actitvity启动多个实例方式

android应用Actitvity启动多个实例方式

最后执行ActivityManagerShellCommnad.exec()->onCommand()






相关文章:

  • 2022-12-23
  • 2021-11-18
  • 2022-01-20
  • 2022-12-23
  • 2021-12-21
  • 2022-01-01
  • 2021-11-24
猜你喜欢
  • 2021-12-27
  • 2021-04-05
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案