日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Android 7.0 行為變更 | Android Developers NDK 應用鏈接至平臺庫

 quasiceo 2017-03-14

NDK 應用鏈接至平臺庫


從 Android 7.0 開始,系統(tǒng)將阻止應用動態(tài)鏈接非公開 NDK 庫,這種庫可能會導致您的應用崩潰。此行為變更旨在為跨平臺更新和不同設備提供統(tǒng)一的應用體驗。即使您的代碼可能不會鏈接私有庫,但您的應用中的第三方靜態(tài)庫可能會這么做。因此,所有開發(fā)者都應進行相應檢查,確保他們的應用不會在運行 Android 7.0 的設備上崩潰。如果您的應用使用原生代碼,則只能使用公開 NDK API。

您的應用可通過以下三種方式嘗試訪問私有平臺 API:

  • 您的應用直接訪問私有平臺庫。您應更新您的應用以添加該應用的庫副本,或使用公開 NDK API
  • 您的應用使用一個可訪問私有平臺庫的第三方庫。即使您確定您的應用不會直接訪問私有庫,您仍應針對此情景測試您的應用。
  • 您的應用引用一個其 APK 中未包含的庫。例如,如果您嘗試使用您自己的 OpenSSL 副本,但忘記將它與應用的 APK 進行捆綁,則可能會出現(xiàn)此情況。正常情況下,此應用可在包含 libcrypto.so 的 Android 平臺版本上運行。不過,此應用在不包含此庫的新版 Android(例如,Android 6.0 和更高的版本)上會崩潰。為修復此問題,請確保您的 APK 捆綁您的所有非 NDK 庫。

應用不應使用 NDK 中未包含的原生庫,因為這些庫可能會發(fā)生更改或在不同 Android 版本之間的可用性不同。例如,從 OpenSSL 切換至 BoringSSL 即屬于此類更改。此外,由于不屬于 NDK 中的平臺庫沒有兼容性要求,因此不同的設備可能提供不同級別的兼容性。

為降低此限制可能對當前發(fā)布的應用的影響,面向 API 級別 23 或更低級別的應用在 Android N 上可暫時訪問頗為常用的一組庫,例如 libandroid_runtime.solibcutils.so、libcrypto.solibssl.so。如果您的應用加載其中某個庫,logcat 會生成一個警告,并在目標設備上顯示一個 Toast 來通知您。如果您看到這些警告,您應更新您的應用以添加該應用自己的庫副本,或僅使用公開 NDK API。將來發(fā)布的 Android 平臺可能會完全限制對私有庫的使用,并導致您的應用崩潰。

所有應用在調用既非公開又不可暫時訪問的 API 時都會生成一個運行時錯誤。結果就是 System.loadLibrarydlopen(3) 同時返回 NULL,并可能導致您的應用崩潰。您應檢查應用代碼以移除對私有平臺 API 的使用,并使用預覽版設備或模擬器全面測試應用。如果您不確定您的應用是否使用私有庫,您可以檢查 logcat 以識別運行時錯誤。

下表描述的是根據(jù)應用使用的私有原生庫及其目標 API 級別 (android:targetSdkVersion),應用預期顯示的行為。

目標 API 級別 通過動態(tài)鏈接器進行運行時訪問 N Developer Preview 行為 最終 Android N 版本行為 未來的 Android 平臺行為
公開 NDK 任意 可訪問 合乎預期 合乎預期 合乎預期
私有(暫時可訪問的私有庫) 23 或更低 暫時可訪問 合乎預期,但您會在目標設備上收到一個 logcat 警告和一條消息。 合乎預期,但您會收到一個 logcat 警告。 運行時錯誤
私有(暫時可訪問的私有庫) 24 或更高 受限 運行時錯誤 運行時錯誤 運行時錯誤
私有(其他) 任意 受限 運行時錯誤 運行時錯誤 運行時錯誤

檢查您的應用是否使用私有庫

為幫助您識別加載私有庫的問題,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 工具,您可以通過運行以下命令生成給定 .so 文件的所有動態(tài)鏈接的共享庫列表:

aarch64-linux-android-readelf -dW libMyLibrary.so

更新您的應用

通過下面的一些步驟,您可以修復上述類型的錯誤并確保您的應用不會在將來的更新版平臺上崩潰:

  • 如果您的應用使用私有平臺庫,您應更新它,以添加該應用自己的庫副本或使用公開 NDK API。
  • 如果您的應用使用訪問私有符號的第三方庫,則聯(lián)系庫作者以更新庫。
  • 請確保將您的所有非 NDK 庫與您的 APK 打包在一起。
  • 使用標準 JNI 函數(shù)而非來自 libandroid_runtime.sogetJavaVMgetJNIEnv
    AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h>
    AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
    JavaVM::AttachCurrentThread from <jni.h>.
    
  • 使用 __system_property_get 而非來自 libcutils.so 的私有 property_get 符號。為此,請使用 __system_property_get 及以下 include 函數(shù):
    #include <sys/system_properties.h>

    :系統(tǒng)屬性的可用性和內容未通過 CTS 進行測試。應執(zhí)行進一步修復以避免同時使用這些屬性。

  • 使用來自 libcrypto.soSSL_ctrl 符號的本地版本。例如,您應在您的 .so 文件中靜態(tài)鏈接 libcyrpto.a,或從 BoringSSL/OpenSSL 添加一個動態(tài)鏈接的 libcrypto.so 版本,并將其打包到您的 APK 中。

Android for Work

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多