今天在開發(fā)的過程中忽然遇到如下彈窗

納尼?這是什么鬼?
后續(xù)通過搜索資料發(fā)現(xiàn)這個是 Android P 引入非SDK接口限制,那哪些是SDK接口,哪些是非SDK接口呢?
區(qū)分SDK和非SDK接口
一般來說,公共SDK接口是在Android框架中的那些接口,非SDK接口是自己去看源碼發(fā)現(xiàn)某些內(nèi)部方法可以使用,然后通過反射直接調(diào)用,但是這個方法是官方更新時可能會進行修改的,而且不會通知你,所以為了保證程序的健壯性,推薦用SDK正式推出的接口。針對非SDK接口官方也有檢測工具。
為了最大程度地減少非SDK限制對您的開發(fā)工作流的影響,將非SDK接口劃分為多個列表,這些列表定義了限制使用它們的嚴(yán)格程度,具體取決于所針對的API級別。下表描述了每個列表:

那觸發(fā)彈窗的就是里面所說的 greylist 列表,那不同的sdk版本有哪些區(qū)別?
確定接口屬于哪個列表
Android 10
對于Android 10(API級別29),以下文件描述了所有非SDK接口及其對應(yīng)的列表:hiddenapi-flags.csv
Android 9
對于Android 9(API級別28),以下文本文件包含不受限制(灰名單)的非SDK API列表:hiddenapi-light-greylist.txt
通過 AOSP 獲得該列表
通過使用 AOSP,你可以生成 hiddenapi-flags.csv 文件,這個文件就包含了所有非sdk接口的列表,那該怎么用?
AOSP 下載地址:https://source.android.com/setup/build/downloading
下載成功之后執(zhí)行:
m out/soong/hiddenapi/hiddenapi-flags.csv
然后你可以在以下路徑看到 hiddenapi-flags.csv 文件
out/soong/hiddenapi/hiddenapi-flags.csv
訪問非SDK接口會導(dǎo)致什么問題呢?

如何測試APP中是否包含了受限的非SDK接口?
debug模式下查看 logcat
將應(yīng)用安裝在 Android 9 或者以后的機器上,通過 logcat 查看,會有如下所示的輸出:
Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)
利用 StrictMode API
利用 StrictMode 的API也可以測試是否使用了非SDK接口,使用 detectNonSdkApiUsage方法可以開啟這個檢測,然后通過 penaltyListener 去監(jiān)聽回調(diào),方法如下:

使用 Veridex 工具進行測試
您還可以使用veridex靜態(tài)分析工具對APK進行分析。veridex工具會掃描APK的整個代碼庫,包括任何第三方庫,并報告找到的非SDK接口的使用情況。
但是 veridex 工具有它自己的局限性:
- 它無法通過JNI檢測調(diào)用。
- 它只能通過反射來檢測調(diào)用的子集。
- 它對無效代碼路徑的分析僅限于API級別檢查。
- 它只能在支持SSE4.2和POPCNT指令的計算機上運行。
1)windows
Windows 沒有提供可以直接安裝的二進制文件,但是可以通過安裝 Linux 子系統(tǒng)(適用于 Linux 的 Windows 子系統(tǒng)),安裝參考:https://docs.microsoft.com/en-us/windows/wsl/install-win10
這個安裝完成之后就可以到命令行下載 veridex 工具,
下載地址:https://android.googlesource.com/platform/prebuilts/runtime/+archive/master/appcompat.tar.gz
- 下載完成后解壓
appcompat.tar.gz文件 - 在解壓文件夾中找出
veridex-linux.zip并進行解壓 - 命令行進入該文件夾并執(zhí)行如下指令
./appcompat.sh --dex-file=your-app.apk
2)MacOS
- 下載 veridex 工具:https://android.googlesource.com/platform/prebuilts/runtime/+archive/master/appcompat.tar.gz
- 下載完成后解壓
appcompat.tar.gz文件 - 在解壓文件夾中找出
veridex-mac.zip并進行解壓 - 命令行進入該目錄并執(zhí)行如下指令
/appcompat.sh --dex-file=/path-from-root/your-app.apk
3)Linux
同Windows中安裝完Linux之后的步驟
利用 Android Studio 的 lint 工具
利用 Play Console
其他問題
如何啟用對非SDK接口的訪問?
您可以通過使用adb命令更改API策略強制啟用對開發(fā)設(shè)備上非SDK接口的訪問,您使用的命令因API級別而異,這些命令不需要root用戶的設(shè)備。
1)Android 10(API級別29)
adb shell settings put global hidden_api_policy 1
還原默認(rèn)設(shè)定
adb shell settings delete global hidden_api_policy
2)Android 9 (API level 28)
adb shell settings put global hidden_api_policy_pre_p_apps 1
adb shell settings put global hidden_api_policy_p_apps 1
還原設(shè)定
adb shell settings delete global hidden_api_policy_pre_p_apps
adb shell settings delete global hidden_api_policy_p_apps
修改API策略中整數(shù)含義解釋如下:
- 0:禁用所有非SDK接口檢測。使用此設(shè)置會禁用所有非SDK接口使用的日志消息,并阻止您使用StrictModeAPI測試您的應(yīng)用。不建議使用此設(shè)置。
- 1:啟用對所有非SDK接口的訪問,但會打印日志消息,并帶有警告,說明任何非SDK接口的使用情況。使用此設(shè)置還可以使您使用StrictModeAPI測試應(yīng)用。
- 2:禁止使用屬于
blocklist的非SDK接口或在目標(biāo)API級別被有條件阻止的非SDK接口。
參考
https://developer.android.com/distribute/best-practices/develop/restrictions-non-sdk-interfaces
https://stackoverflow.com/questions/53864764/detected-problems-with-api-compatibility