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並不會被新安裝的覆蓋。