標籤:
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並不會被新安裝的覆蓋。
android 靜態和動態設定 Receiver的 android:enabled值