Android 開發(fā)者 | 應(yīng)用兼容性注意事項(xiàng)

image.png

由于國內(nèi) Android 開發(fā)環(huán)境的特殊性,兼容性一直是很多開發(fā)者極為關(guān)注的問題。為此,我們特意請來了負(fù)責(zé) Android 在中國兼容性問題的 Google 工程師為大家對一些常見問題做出解答,來看看我的工程師提到了哪些要點(diǎn)吧!

"大家好,我是谷歌的開發(fā)技術(shù)推廣工程師,主要負(fù)責(zé) Android 在中國的兼容性問題。我們發(fā)現(xiàn),每次有 Android 新版本發(fā)布時,國內(nèi)有很多應(yīng)用由于沒有遵循最佳開發(fā)實(shí)踐,或使用了依賴于底層非公開 API 的 “黑科技”,而無法直接在新版本上運(yùn)行,必須做出相當(dāng)?shù)拇a修改來進(jìn)行兼容。在這篇文章中,我們總結(jié)了關(guān)于應(yīng)用開發(fā)在兼容性方面的注意事項(xiàng),希望大家在開發(fā)過程中多加注意。"

不要使用私有 API

私有 API 是指 Android 系統(tǒng)內(nèi)部使用、并未提供公開接口的 API,開發(fā)者可能通過 Java 反射等技術(shù)來調(diào)用這些私有 API。但是,這么做是很危險的:私有 API 沒有任何公開文檔,必須查看源代碼才能理解其行為邏輯。

私有 API 的接口信息、函數(shù)簽名(包括參數(shù)列表和返回值)、行為邏輯都有可能在下個 Android 版本中被大幅修改,甚至 API 本身也可能被刪除。這會導(dǎo)致使用私有 API 的應(yīng)用在新的 Android 版本中無法運(yùn)行,或運(yùn)行時產(chǎn)生不符合預(yù)期的行為,開發(fā)者必須投入相當(dāng)?shù)难邪l(fā)資源保持其在未來每個 Android 新版本中的適配。

直接使用底層的私有 API 有可能會繞過一些 Android 對用戶的安全性和隱私性方面的保護(hù),不但影響用戶體驗(yàn)、妨害用戶隱私,也很可能會被 Google Play Protect 判定為惡意軟件而提示用戶卸載應(yīng)用。

所以,我們強(qiáng)烈建議開發(fā)者只使用 Android 公開的 API 進(jìn)行應(yīng)用開發(fā)。公開 API 有詳細(xì)的技術(shù)文檔和支持渠道,未來的 Android 新版本也會保證公開 API 的兼容性(即使有改動,也會在文檔中詳細(xì)闡明)。

如果您有合理的理由,必須使用某個私有 API,請告訴我們!我們很樂意聆聽和討論,并會在充分評估必要性和可行性后,在 Android 系統(tǒng)或 Support Library 中提供方案來滿足合理的功能需求。

不要直接調(diào)用 dex2oat

從一開始,dex2oat 就被設(shè)計為系統(tǒng)內(nèi)部使用的編譯部署工具,Android 從來都未支持過開發(fā)者直接調(diào)用 dex2oat 的場景。我們會持續(xù)而不定期地對這個工具進(jìn)行優(yōu)化,而很多時候其行為變更(如:生成的文件及其格式)都是與之前不兼容的。在大多數(shù)情況下,標(biāo)準(zhǔn)的類加載器(BaseDexClassLoader / DexClassLoader / PathClassLoader)無法找到或使用由直接調(diào)用 dex2oat 生成的文件。

如果您需要從內(nèi)存中加載 dex 文件,而不愿在存儲中留下痕跡,請使用 Android O 中新增的加載器 InMemoryDexClassLoader。

不要注入或篡改 Android Studio 生成的 dex 和 so 文件

image

Android Studio 生成的 dex 文件雖然有公開的布局格式,但具體內(nèi)容還是會在運(yùn)行時被系統(tǒng)在后臺進(jìn)行編譯優(yōu)化。如果您在 dex 文件中寫入自定義的內(nèi)容,很可能這些自定義的寫入操作與系統(tǒng)優(yōu)化發(fā)生沖突,以致自定義的內(nèi)容被擦除或覆蓋,甚至導(dǎo)致優(yōu)化后的 dex 在執(zhí)行時直接崩潰。

Android Studio 生成的 so 文件包含一些元數(shù)據(jù)(如 ELF headers 和 section headers),以備動態(tài)鏈接器進(jìn)行完整性檢查。篡改 so 文件并不會帶來安全性的提升(很多工具可以重新生成元數(shù)據(jù)),反而可能導(dǎo)致應(yīng)用無法在未來的 Android 版本中無法啟動(由于動態(tài)鏈接器可能執(zhí)行更嚴(yán)格的檢查)。更多關(guān)于 so 文件的要求,請查看以下鏈接中的文檔(會有不定期更新):

android.googlesource.com/platform/bi…

不要干擾或篡改系統(tǒng)內(nèi)部加載 dex 的邏輯

Android 系統(tǒng)內(nèi)部加載 dex 的邏輯比較復(fù)雜,會考慮很多因素(如安全性、隱私性等),其具體行為邏輯也可能會在新版本中加以修改。如果您干擾或篡改了 dex 的加載邏輯,不但會增加安全性方面的風(fēng)險,也很可能在新的系統(tǒng)更新后不再工作,甚至導(dǎo)致應(yīng)用無法運(yùn)行。

不要使用 DexFile 類

DexFile 類已經(jīng)在 Android O 中被廢棄。DexFile 在應(yīng)用開發(fā)中的使用暴露了很多問題,導(dǎo)致應(yīng)用崩潰或錯誤結(jié)果。

比如,當(dāng)多個類加載器試圖使用同一個 DexFile 對象來定義某個類時,Android 系統(tǒng)會拋出 InternalError,其錯誤信息為 “Attempt to register dex file <filename> with multiple class loaders”。這是因?yàn)檫\(yùn)行環(huán)境將 DexFile 與一些附加的內(nèi)部狀態(tài)信息進(jìn)行關(guān)聯(lián),而這些內(nèi)部狀態(tài)信息不能在類加載器之間進(jìn)行共享。

所以,請不要在應(yīng)用代碼中再使用 DexFile 類型。

及時升級第三方 SDK

在中國的 Android 生態(tài)中,應(yīng)用經(jīng)常依賴的第三方 SDK(特別是加固和熱修復(fù)框架)會有很多直接的 dex 操作,而導(dǎo)致應(yīng)用在 Android 版本升級時無法正常運(yùn)行。我們也開始與一些常見的 SDK 提供商合作(并計劃覆蓋更多),在 Android 新的預(yù)覽版本中盡早解決兼容性問題。對于應(yīng)用開發(fā)者來說,只需要經(jīng)常檢查第三方 SDK 的升級公告,及時升級至其最新版本,就能解決大部分與其相關(guān)的兼容性問題。

image

看了工程師劃的重點(diǎn),不知您是否有種豁然開朗的感覺呢?面對復(fù)雜的中國 Android 開發(fā)生態(tài),很多朋友都會遇到一些特殊的問題,為了更好地服務(wù)于國內(nèi)的 Android 開發(fā)者,我們會在收集到一定量特定領(lǐng)域的咨詢后,為大家?guī)?Google 工程師的解決建議及規(guī)避方法。

您還有哪些難以解決的開發(fā)問題呢?歡迎留言!

image
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容