NDK 應用鏈接至平臺庫從 Android 7.0 開始,系統(tǒng)將阻止應用動態(tài)鏈接非公開 NDK 庫,這種庫可能會導致您的應用崩潰。此行為變更旨在為跨平臺更新和不同設備提供統(tǒng)一的應用體驗。即使您的代碼可能不會鏈接私有庫,但您的應用中的第三方靜態(tài)庫可能會這么做。因此,所有開發(fā)者都應進行相應檢查,確保他們的應用不會在運行 Android 7.0 的設備上崩潰。如果您的應用使用原生代碼,則只能使用公開 NDK API。 您的應用可通過以下三種方式嘗試訪問私有平臺 API:
應用不應使用 NDK 中未包含的原生庫,因為這些庫可能會發(fā)生更改或在不同 Android 版本之間的可用性不同。例如,從 OpenSSL 切換至 BoringSSL 即屬于此類更改。此外,由于不屬于 NDK 中的平臺庫沒有兼容性要求,因此不同的設備可能提供不同級別的兼容性。
為降低此限制可能對當前發(fā)布的應用的影響,面向 API 級別 23 或更低級別的應用在 Android N 上可暫時訪問頗為常用的一組庫,例如
所有應用在調用既非公開又不可暫時訪問的 API 時都會生成一個運行時錯誤。結果就是
下表描述的是根據(jù)應用使用的私有原生庫及其目標 API 級別 (
檢查您的應用是否使用私有庫為幫助您識別加載私有庫的問題,logcat 可能會生成一個警告或運行時錯誤。例如,如果您的應用面向 API 級別 23 或更低級別,并在運行 Android 7.0 的設備上嘗試訪問私有庫,您可能會看到一個類似于下面所示的警告: 03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so" ("/system/lib/libandroid_runtime.so") needed or dlopened by "/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible for the namespace "classloader-namespace" - the access is temporarily granted as a workaround for http://b/26394120 這些 logcat 警告通知您哪個庫正在嘗試訪問私有平臺 API,但不會導致您的應用崩潰。但是,如果應用面向 API 級別 24 或更高級別,logcat 會生成以下運行時錯誤,您的應用可能會崩潰: java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so" ("/system/lib/libcutils.so") needed or dlopened by "/system/lib/libnativeloader.so" is not accessible for the namespace "classloader-namespace" at java.lang.Runtime.loadLibrary0(Runtime.java:977) at java.lang.System.loadLibrary(System.java:1602)
如果您的應用使用動態(tài)鏈接到私有平臺 API 的第三方庫,您可能也會看到上述 logcat 輸出。利用 Android 7.0DK 中的 readelf 工具,您可以通過運行以下命令生成給定 aarch64-linux-android-readelf -dW libMyLibrary.so 更新您的應用通過下面的一些步驟,您可以修復上述類型的錯誤并確保您的應用不會在將來的更新版平臺上崩潰:
Android for Work |
|