從 2018 年 3 月初我們發(fā)布 Android P 開發(fā)者預(yù)覽版以來,很多開發(fā)者都對(duì)當(dāng)前常見應(yīng)用在 Android P 上做了一些兼容性測(cè)試,我們?cè)谶@里總結(jié)了一些常見的問題,以及它們發(fā)生的原因和建議的修改措施。
問題 1: 假設(shè) android.os.Build.VERSION.RELEASE 為數(shù)值類型
原因:
對(duì)于即將推出的 Android 新版本的預(yù)覽版,這些值可能是字母數(shù)字 (如 “PPR” 或 “P”),因此在嘗試將 “P” 解析為整數(shù)時(shí)會(huì)導(dǎo)致崩潰。
建議:
應(yīng)用把 RELEASE 的值作為字符串類型來處理。
問題 2: 使用的第三方 SDK 版本過低,不兼容 Android P
原因:
在中國(guó)的 Android 生態(tài)中,應(yīng)用經(jīng)常依賴的第三方 SDK (特別是加固和熱修復(fù)框架) 會(huì)和系統(tǒng)底層緊密集成 (如使用非公開的接口),而導(dǎo)致應(yīng)用在 Android 版本升級(jí)時(shí)無(wú)法正常運(yùn)行。我們也開始與一些常見的 SDK 提供商合作 (并計(jì)劃覆蓋更多),在 Android 新的預(yù)覽版本中盡早解決兼容性問題。
建議:
經(jīng)常檢查第三方 SDK 的升級(jí)公告,及時(shí)升級(jí)至其最新版本。
如果您使用的第三方 SDK 尚不支持 Android 新版本,請(qǐng)報(bào)告給其提供商,幫助推動(dòng)它解決兼容性問題。
問題 3: 開啟應(yīng)用時(shí)顯示 'Detected problems with API compatibility',或調(diào)用非 SDK 接口時(shí)遭遇 NoSuchFieldException 或 NoSuchMethodException
原因:
非 SDK 接口指的是 Android 系統(tǒng)內(nèi)部使用、并未提供在 SDK 中的接口,開發(fā)者可能通過 Java 反射、JNI 等技術(shù)來調(diào)用這些接口。但是,這么做是很危險(xiǎn)的:非 SDK 接口沒有任何公開文檔,必須查看源代碼才能理解其行為邏輯。
非 SDK 接口的函數(shù)簽名 (包括參數(shù)列表和返回值)、行為邏輯都有可能在下個(gè) Android 版本中被大幅修改,甚至 API 本身也可能被刪除。這會(huì)導(dǎo)致使用非 SDK 接口的應(yīng)用在新的 Android 版本中無(wú)法運(yùn)行,或運(yùn)行時(shí)產(chǎn)生不符合預(yù)期的行為,開發(fā)者必須投入相當(dāng)?shù)难邪l(fā)資源保持其在未來每個(gè) Android 新版本中的適配。
直接使用底層的非 SDK 接口有可能會(huì)繞過一些 Android 對(duì)用戶的安全性和隱私性方面的保護(hù),不但影響用戶體驗(yàn)、妨害用戶隱私,也很可能會(huì)被 Google Play Protect 判定為惡意軟件而提示用戶卸載應(yīng)用。
從 Android P 開始,系統(tǒng)會(huì)限制非 SDK 接口的使用。
建議:
只使用 Android SDK 中的公開接口進(jìn)行應(yīng)用開發(fā)。公開 SDK 接口有詳細(xì)的技術(shù)文檔和支持渠道,未來的 Android 新版本也會(huì)保證公開 SDK 接口的兼容性 (即使有改動(dòng),也會(huì)在文檔中詳細(xì)闡明)。
請(qǐng)盡早在 Android P 預(yù)覽版中測(cè)試您的應(yīng)用,您可以運(yùn)行并操作應(yīng)用,然后在 adb logcat 中查找類似下方的內(nèi)容,其中包含了應(yīng)用調(diào)用的非 SDK 接口名,所屬黑/灰名單和調(diào)用的方式:
Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI)
Accessing hidden method Landroid/app/ActivityThread;->currentActivityThread()Landroid/app/ActivityThread; (dark greylist, reflection)
如果您有合理的理由,必須使用某個(gè)非 SDK 接口,請(qǐng)?jiān)谖恼孪路搅粞越o我們,我們非常期待聆聽和與您進(jìn)行討論,并會(huì)在充分評(píng)估必要性和可行性后,提供可能的方案來滿足合理的功能需求。
問題 4: 直接調(diào)用 dex2oat,或者使用不支持 / 不正確的方式編譯 dex 文件
原因:
從一開始,dex2oat 就被設(shè)計(jì)為系統(tǒng)內(nèi)部使用的編譯部署工具,Android 從來都未支持過開發(fā)者直接調(diào)用 dex2oat 的場(chǎng)景。我們會(huì)持續(xù)而不定期地對(duì)這個(gè)工具進(jìn)行優(yōu)化,而很多時(shí)候其行為變更 (如: 生成的文件及其格式) 都是與之前不兼容的。在大多數(shù)情況下,標(biāo)準(zhǔn)的類加載器 (BaseDexClassLoader / DexClassLoader / PathClassLoader) 無(wú)法找到或使用由直接調(diào)用 dex2oat 生成的文件。
此外請(qǐng)注意,從 Android O 開始,BaseDexClassLoader 和 DexClassLoader 構(gòu)造函數(shù)中的 “optimizedDirectory” 參數(shù)已廢棄,并在加載 dex 文件時(shí)不起作用。
建議:
如果您需要從內(nèi)存中加載 dex 文件,而不愿在存儲(chǔ)中留下痕跡,請(qǐng)使用 Android O 中新增的加載器 InMemoryDexClassLoader。
問題 5: 注入或篡改 Android Studio 生成的 dex 和 so 文件
原因:
Android Studio 生成的 dex 文件雖然有公開的布局格式,但具體內(nèi)容還是會(huì)在運(yùn)行時(shí)被系統(tǒng)在后臺(tái)進(jìn)行編譯優(yōu)化。如果您在 dex 文件中寫入自定義的內(nèi)容,很可能這些自定義的寫入操作與系統(tǒng)優(yōu)化發(fā)生沖突,以致自定義的內(nèi)容被擦除或覆蓋,甚至導(dǎo)致優(yōu)化后的 dex 在執(zhí)行時(shí)直接崩潰。
Android Studio 生成的 so 文件包含一些元數(shù)據(jù) (如 ELF headers 和 section headers),以備動(dòng)態(tài)鏈接器進(jìn)行完整性檢查。篡改 so 文件并不會(huì)帶來安全性的提升 (很多工具可以重新生成元數(shù)據(jù)),反而可能導(dǎo)致應(yīng)用無(wú)法在未來的 Android 版本中啟動(dòng) (由于動(dòng)態(tài)鏈接器可能執(zhí)行更嚴(yán)格的檢查)。更多關(guān)于 so 文件的要求,您可在公眾號(hào)平臺(tái)發(fā)送信息 “so文件” 獲取相關(guān)鏈接。
建議:
不要修改 Android Studio 生成的 dex 和 so 文件。
問題 6: 應(yīng)用在 Android P 上啟動(dòng)時(shí)顯示 “This app was built for an older version of Android and may not work properly...”
原因:
應(yīng)用的 targetSdkVersion 太舊 ( <17>17>
建議:
升級(jí)您應(yīng)用的 targetSdkVersion 至最新版本,您可在公眾號(hào)平臺(tái)發(fā)送信息 “targetsdkversion” 獲取相關(guān)文檔鏈接。
問題 7: 應(yīng)用在特長(zhǎng)屏幕上未能正確顯示,部分內(nèi)容超出屏幕
原因:
Android O 開始支持特長(zhǎng)屏幕,而且已經(jīng)有很多廠商開始發(fā)布特長(zhǎng)屏幕的手機(jī)。應(yīng)用對(duì)屏幕的顯示比例做出錯(cuò)誤的假設(shè),而未能支持 16:9 以上的縱橫比,進(jìn)而影響用戶體驗(yàn)。
建議:
修改您的應(yīng)用,使他能夠適應(yīng)不同的屏幕尺寸 (包括 16:9 以上的縱橫比)。
如果自適應(yīng)式 UI 不適合您的場(chǎng)景,可以考慮在 manifest 中的
問題 8: 應(yīng)用在特長(zhǎng)屏幕上未能正確顯示,上下出現(xiàn)黑邊
原因:
Android O 開始支持特長(zhǎng)屏幕,而且已經(jīng)有很多廠商開始發(fā)布特長(zhǎng)屏幕的手機(jī)。應(yīng)用對(duì)未能支持 16:9 以上的縱橫比會(huì)在特長(zhǎng)屏幕的設(shè)備上啟用兼容模式,把應(yīng)用邊緣的顯示空間以黑色填充。
建議:
升級(jí)您應(yīng)用的 targetSdkVersion 至最新版本,您可在公眾號(hào)平臺(tái)發(fā)送信息 “targetsdkversion” 獲取相關(guān)文檔鏈接。
請(qǐng)參考下列 Android P 相關(guān)文檔,使您的應(yīng)用盡早兼容 Android P:
- 設(shè)置 SDK 和模擬器
https://developer.android.google.cn/preview/setup-sdk.html
- 遷移指南
https://developer.android.google.cn/preview/migration.html
- 行為變更
https://developer.android.google.cn/preview/behavior-changes.html
- 新功能及 API
https://developer.android.google.cn/preview/features.html
如果您在 Android P 的兼容性工作中有什么經(jīng)驗(yàn)和體會(huì),歡迎在文章下方留言與我們分享。謝謝!
聯(lián)系客服