最近系统同事分析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进程下拉起。
如何用am应用启动RadioInfo?
由于RadioInfo intent-filter 的action是android.intent.action.MAIN。可以通过-a参数拉起。
[-a <ACTION>]
操作如下,没有报错。但是手机界面弹出选择框,有很多应用供选择。RadioInfo是其中之一。因为基本所有应用都有一个Activity页面的intent-filter 的action是android.intent.action.MAIN。(只有这样应用在桌面点击时才能决定拉起哪个Activity。)
如果要直接拉起RadioInfo,就要用-n参数。如下:
执行这三个命令后,发现有两个RadioInfo页面,说明此Activity有两个实例启动。为何有两个呢?注意,如果将-f 0x18000000去掉,如下三个命令,则只有一个RadioInfo实例启动。
这就要看-f 0x18000000是何含义了。参见Intent.java,关键在于0x8000000 flag.
当为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属性,
那么再去尝试上面的命令就会有warning报错,如下图。因为singleTask属性存在,无论intent的参数如何,只允许一个Activity实例。
am 源码
入口:
接着到ActivityManagerService.java文件中onShellCommand()处理:
最后执行ActivityManagerShellCommnad.exec()->onCommand()