Android P 應用兼容常見錯誤及建議

從 2018 年 3 月初咱們發佈 Android P 開發者預覽版以來,不少開發者都對當前常見應用在 Android P 上作了一些 兼容性測試,咱們在這裏總結了一些常見的問題,以及它們發生的緣由和建議的修改措施。

問題 1: 假設 android.os.Build.VERSION.RELEASE 爲數值類型

緣由:html

對於即將推出的 Android 新版本的預覽版,這些值多是字母數字 (如 「PPR」 或 「P」),所以在嘗試將 「P」 解析爲整數時會致使崩潰。android

建議:安全

應用把 RELEASE 的值做爲字符串類型來處理。app

問題 2: 使用的第三方 SDK 版本太低,不兼容 Android P

緣由:框架

在中國的 Android 生態中,應用常常依賴的第三方 SDK (特別是加固和熱修復框架) 會和系統底層緊密集成 (如使用非公開的接口),而致使應用在 Android 版本升級時沒法正常運行。咱們也開始與一些常見的 SDK 提供商合做 (並計劃覆蓋更多),在 Android 新的預覽版本中儘早解決兼容性問題。函數

建議:工具

常常檢查第三方 SDK 的升級公告,及時升級至其最新版本。佈局

若是您使用的第三方 SDK 尚不支持 Android 新版本,請報告給其提供商,幫助推進它解決兼容性問題。測試

問題 3: 開啓應用時顯示 "Detected problems with API compatibility",或調用非 SDK 接口時遭遇 NoSuchFieldException 或 NoSuchMethodException

緣由:優化

非 SDK 接口指的是 Android 系統內部使用、並未提供在 SDK 中的接口,開發者可能經過 Java 反射、JNI 等技術來調用這些接口。可是,這麼作是很危險的:非 SDK 接口沒有任何公開文檔,必須查看源代碼才能理解其行爲邏輯。

非 SDK 接口的函數簽名 (包括參數列表和返回值)、行爲邏輯都有可能在下個 Android 版本中被大幅修改,甚至 API 自己也可能被刪除。這會致使使用非 SDK 接口的應用在新的 Android 版本中沒法運行,或運行時產生不符合預期的行爲,開發者必須投入至關的研發資源保持其在將來每一個 Android 新版本中的適配。

直接使用底層的非 SDK 接口有可能會繞過一些 Android 對用戶的安全性和隱私性方面的保護,不但影響用戶體驗、妨害用戶隱私,也極可能會被 Google Play Protect 斷定爲惡意軟件而提示用戶卸載應用。

從 Android P 開始,系統會限制非 SDK 接口的使用

建議:

只使用 Android SDK 中的公開接口進行應用開發。公開 SDK 接口有詳細的技術文檔和支持渠道,將來的 Android 新版本也會保證公開 SDK 接口的兼容性 (即便有改動,也會在文檔中詳細闡明)。

請儘早在 Android P 預覽版中測試您的應用,您能夠運行並操做應用,而後在 adb logcat 中查找相似下方的內容,其中包含了應用調用的非 SDK 接口名,所屬黑/灰名單和調用的方式: Accessing hidden field Landroid/os/Message;->flags:I (light greylist, JNI) Accessing hidden method Landroid/app/ActivityThread;->currentActivityThread()Landroid/app/ActivityThread; (dark greylist, reflection)

若是您有合理的理由,必須使用某個非 SDK 接口,請在文章下方留言給咱們,咱們很是期待聆聽和與您進行討論,並會在充分評估必要性和可行性後,提供可能的方案來知足合理的功能需求。

問題 4: 直接調用 dex2oat,或者使用不支持 / 不正確的方式編譯 dex 文件

緣由:

從一開始,dex2oat 就被設計爲系統內部使用的編譯部署工具,Android 歷來都未支持過開發者直接調用 dex2oat 的場景。咱們會持續而不按期地對這個工具進行優化,而不少時候其行爲變動 (如: 生成的文件及其格式) 都是與以前不兼容的。在大多數狀況下,標準的類加載器 (BaseDexClassLoader / DexClassLoader / PathClassLoader) 沒法找到或使用由直接調用 dex2oat 生成的文件。

此外請注意,從 Android O 開始,BaseDexClassLoader 和 DexClassLoader 構造函數中的 「optimizedDirectory」 參數已廢棄,並在加載 dex 文件時不起做用。

建議:

若是您須要從內存中加載 dex 文件,而不肯在存儲中留下痕跡,請使用 Android O 中新增的加載器 InMemoryDexClassLoader。

問題 5: 注入或篡改 Android Studio 生成的 dex 和 so 文件

緣由:

Android Studio 生成的 dex 文件雖然有公開的佈局格式,但具體內容仍是會在運行時被系統在後臺進行編譯優化。若是您在 dex 文件中寫入自定義的內容,極可能這些自定義的寫入操做與系統優化發生衝突,以至自定義的內容被擦除或覆蓋,甚至致使優化後的 dex 在執行時直接崩潰。

Android Studio 生成的 so 文件包含一些元數據 (如 ELF headers 和 section headers),以備動態連接器進行完整性檢查。篡改 so 文件並不會帶來安全性的提高 (不少工具能夠從新生成元數據),反而可能致使應用沒法在將來的 Android 版本中啓動 (因爲動態連接器可能執行更嚴格的檢查)。更多關於 so 文件的要求,您可在公衆號平臺發送信息 「so文件」 獲取相關連接。

建議:

不要修改 Android Studio 生成的 dex 和 so 文件。

問題 6: 應用在 Android P 上啓動時顯示 「This app was built for an older version of Android and may not work properly...」

緣由:

應用的 targetSdkVersion 太舊 ( <17 )

建議:

升級您應用的 targetSdkVersion 至最新版本,您可在公衆號平臺發送信息 「targetsdkversion」 獲取相關文檔連接。

問題7: 應用在特長屏幕上未能正確顯示,部份內容超出屏幕

緣由:

Android O 開始支持特長屏幕,並且已經有不少廠商開始發佈特長屏幕的手機。應用對屏幕的顯示比例作出錯誤的假設,而未能支持 16:9 以上的縱橫比,進而影響用戶體驗。

建議:

修改您的應用,使他可以適應不一樣的屏幕尺寸 (包括 16:9 以上的縱橫比)。

若是自適應式 UI 不適合您的場景,能夠考慮在 manifest 中的 內設置 resizableActivity = false,並加上 android:MaxAspectRatio 來聲明最大支持縱橫比。這會在特長屏幕的設備上啓用兼容模式,把應用邊緣的顯示空間以黑色填充。

問題 8: 應用在特長屏幕上未能正確顯示,上下出現黑邊

緣由:

Android O 開始支持特長屏幕,並且已經有不少廠商開始發佈特長屏幕的手機。應用對未能支持 16:9 以上的縱橫比會在特長屏幕的設備上啓用兼容模式,把應用邊緣的顯示空間以黑色填充。

建議:

升級您應用的 targetSdkVersion 至最新版本,您可在公衆號平臺發送信息 「targetsdkversion」 獲取相關文檔連接。

請參考下列 Android P 相關文檔,使您的應用盡早兼容 Android P:

設置 SDK 和模擬器

遷移指南

行爲變動

新功能及 API

若是您在 Android P 的兼容性工做中有什麼經驗和體會,歡迎在文章下方留言與咱們分享。謝謝!

相關文章
相關標籤/搜索