1. 程式人生 > >Android 開發---對非SDK介面限制的適配

Android 開發---對非SDK介面限制的適配

前言

專案升級到Android Pie(9),需要考慮適配問題.在此做個總結.
Android 9 增加了對非SDK介面訪問的限制,無論你是直接訪問還是通過反射,JNI等間接訪問,都是會被限制的.


SDK介面和非SDK介面有啥區別?

SDK介面是那些官方支援的,Android framework 文件中可以找的.Android framework Package index .那非SDK介面就自然是相反的意思了.


非SDK介面的級別

非SDK介面很對,Google對它按限制程度進行了分類,分為light-greylist(淺灰列表),dark-greylist(深灰列表),blacklist(黑列表).

顏色的加深,限制程度也是隨之加深.

  1. 對於light-greylist,非SDK介面的Methods/fields 還可以繼續使用
  2. 對於dark-greylist,應用的target SDK version 小於28的,非SDK介面還是可以繼續使用的,但是如果target Sdk version 大於等於28的話,就不能用了,會拋exception 如:NoSuchMethodError/NoSuchFieldException.
  3. 對於blacklist 無論你的target SDK version 是多少,都不能用非SDK介面.否則就會出現異常.

注意
對於light-greylist和dark-greylist,他們都屬於grey,灰色的,雖然現在在Android 9上還可以使用,但是在之後的版本中,不能保證還可不可以繼續用,沒準,現在在grey list裡的下個版本就被Google移到 black list列表裡面了

繼續使用非SDK介面導致的結果

上面其實說的也比較清楚了,就是出現異常.下面的表也描述的更具體點

訪問方式 結果
Dalvik指令 引用一個field NoSuchFieldError thrown
Dalvik指令 引用一個method NoSuchMethodError thrown
通過Class.getDeclaredField() or Class.getField()反射 NoSuchFieldException thrown,Non-SDK members not in results
通過Class.getDeclaredMethod(), Class.getMethod()反射 NoSuchMethodException thrown,Non-SDK members not in results
JNI 通過 env->GetFieldID()方式 NULL returned, NoSuchFieldError thrown
JNI 通過 env->GetMethodID()方式 NULL returned, NoSuchMethodError thrown

非SDK介面列表

上面說說了,有三種非SDK介面列表,如果我們想知道這些列表裡面的具體有哪些內容,可以進入Google提供的列表索引裡去檢視,看看具體是哪些限制的method,field.

  1. 淺灰列表(light-greylist)
  2. 深灰列表(dark-greylist)
  3. 黑列表(blacklist)

定位非SDK介面

  1. 你可以在Android 9的裝置上面執行你的app,如果你的APP有訪問非SDK介面的話,會打印出相關的log資訊,來幫助你定位,解決非SDK介面問題.log的資訊樣式如下:
    Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)

  2. Android 9 支援通過使用StrictMode的相應Api來檢測非SDK介面的使用.通過使用detectNonSdkApiUsage 方法來啟用檢測功能,檢測功能的啟用越早啟用越好,官方建議是在application的onCreate方法中呼叫.關於使用這個方法來檢測非SDK介面的呼叫,大家可以自行去原始碼中看該方法的使用,有註釋說明,很容易上手,在此就不再贅述.

  3. 通過Google提供的檢測分析工具veridex來,檢測非SDK介面的使用情況.veridex的下載地址如下:
    veridex download address

我的平臺的是Linux的,所以把veridex-linux.zip 解壓後,cd 進入,使用./appcompat.sh --dex-file = test.apk(apk file location) 命令即可完成檢測.
效果如下:

在這裡插入圖片描述

從veridex下載列表上面只看到了適合Linux平臺的,Mac平臺的veridex壓縮包,沒看到Windows的,網上有看到說Windows平臺的不能用這個工具,但是這邊試了與veridex-linux.zip同級目錄下的appcompat.sh指令碼,發現也可以實現相同的檢測效果.所以有點懷疑,但是沒有Windows的裝置來測試,如果有試過的可以把結果告知一下.

結語

定位瞭解到專案中非SDK介面的使用情況後,就可以做出對應的調整,完成適配,避免crash.如果必須要用某種非SDK介面的話,可以向Google提出申請,請求地址如下:
https://issuetracker.google.com/issues/new?component=328403&template=1027267