0x 01 前提约束:
0x001
静态检查:指用action限定Intent,并使用包管理器的queryBroadCastReceivers方法,在flags字段置为0时查找ResolveInfo,检查结果是指它有没有找到组件。
0x002
动态检查:指在指定 包名&类全路径名构成的ComponentName后,调用包管理器的getComponentEnabledSetting方法,得到它的状态值,注意它是一个Int类型,可能取值及意义如下所列。
0x003
动态修改:指在指定 包名&类全路径名构成的ComponentName后,调用包管理器的setComponentEnabledSetting方法,传入下面的三个值中的任意一个,设置enabled字段。
0x004
PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
Int 值为0 ,指在manifest中没有显示声明
PackageManager.COMPONENT_ENABLED_STATE_ENABLED
Int 值为1 ,指在manifest中声明为 android:enabled=”true”
PackageManager.COMPONENT_ENABLED_STATE_DISABLED
Int 值为2 ,指在manifest中声明为 android:enabled=”false”
0x02 Demo 结果总结:
0x001 使用静态方式,修改不了enabled字段的值。
0x002 无论在manifest中被声明为true|false|默认,其对应动态检查结果都是0(还未动态改)。
0x003 对应在manifest中显示声明为 android:enabled=”true”时,无论动态修改值(0|1|2),使用静态检查时都是返回true;当动态修改它的值为2时,收不到广播,(0|1)时能收到。
0x004 对应在manifest中显示声明为 android:enabled=”false”时,如果程序动态将它的值修改成1时,使用静态检查可以找到组件,且其值仍然为false,但是可以收到广播,其它值(0|2)时,找不到对应组件,也收不到广播。
0x005 对应在manifest中没有显示声明时,则,动态修改它的值为2时,静态检查找不到对应组件,也收不到广播,其它值(0|1)时,静态检查值为true且能收到广播。
0x03 预备实现:
0x001
在sdk 中生成优先级时,对于检查push必须的Receivers:
先静态检查,看能否找到对应的组件,如果没有找到组件(包括根本就没有声明Receiver时,注意是没有找到组件,并不是“找到组件,只是值为false”),则直接返回优先级为0,否则默认检查通过,按照优先级生成算法生成优先级。
0x002
一种 case:一开始时在manifest中配置成android:enabled=”false”, 然后在将来的某个时刻尝试启用这个组件,即使得它可以收到广播。由以上结果知,如果不动态修改它的值,那么默认为0,静态检查是找不到这个组件,从而该广播也不能正常被使用。所以,在启用时,执行:动态将其值改为1,然后在重新调用startWork时进行新的一轮静态检查,这是发现它是通过的,所以可以生成优先级。
0x003
如果想关闭一个集成百度push的app,只要使得它的优先级降为0,可以发现:如果动态的将它们的值设置为2,然后再调用starWork进行新一轮静态检查时,将会发现找不到,从而将优先级置为0。
静态设置 |
动态设置 |
预期状态 |
静态值 |
可找到组件 |
可收到广播 |
没显示声明 |
无 |
True |
True |
True |
True |
DEFAULT |
True |
True |
True |
True |
|
ENABLED |
True |
True |
True |
True |
|
DISABLED |
False |
True |
False |
False |
|
True |
无 |
True |
True |
True |
True |
DEFAULT |
True |
True |
True |
True |
|
ENABLED |
True |
True |
True |
True |
|
DISABLED |
False |
False |
False |
False |
|
False |
无 |
False |
—— |
False |
False |
DEFAULT |
False |
—— |
False |
False |
|
ENABLED |
True |
False |
True |
True |
|
DISABLED |
False |
—— |
False |
False |
|
没有注册 |
—— |
False |
False |
False |
False |
从上面的表中可以得到,不论是哪种分类,只要动态将其置为ENABDLED,则静态检查都可以收到,同时也可以收到广播,但是,如果将其动态置为DISABLED,则几种情况下静态都检测不到组件。所以得在调用startWork时,只做静态检查(检查能否找到组件,而不是它的activityInfo.enabled字段的值是true还是false)。
0x04 注:测试中发现
0x001
在动态修改了组件的DISABLED/ENABDLED状态时,当应用退出或者重启后,这个动态修改的结果是持久的。
0x002
如果机子没有卸载,只是重装,则这些DISABLED/ENABDLED并不会被新安装的覆盖。