潜在问题:重定位会强迫使代码页面可写入,并会增长内存中的脏页数量,这异常浪费内存。大年夜 Android K (API 19) 开端,动态链接器宣布了有关文本重定位的警告,而在 API 23 及更高版本中,它拒绝加载包含文本重定位的代码。
受 Android 平台其他改进的影响,Android M 和 N 中的动态链接器对于编写整洁且具有跨平台兼容性的本机代码提出了更为严格的请求;知足这些请求的本机代码才能顺利完成加载。为确保安稳过渡到较新的 Android 版本,应用的本机代码必须遵守这些规矩和建议。
下面,我们将重申并具体解释与本机代码加载有关的各项变革及其影响,以及您可以采取哪些办法来避免出现问题。
所需对象:在 NDK 中,每个架构都有一个 <arch>-linux-android-readelf 二进制文件(如 arm-linux-androideabi-readelf 或 i686-linux-android-readelf,位于 toolchains/ 下),但您可以对任何架构应用 readelf,因为我们将只进行根本检查。在 Linux 上,您须要为 readelf 安装“binutils”法度榜样包,为 scanelf 安装“pax-utils”法度榜样包。
私有 API(大年夜 API 24 开端实施)
本机库只能应用公共 API,且不得链接到非 NDK 平台库。此规矩大年夜 API 24 开端实施,此后应用便无法再加载非 NDK 平台库。此规矩由动态链接器履行,是以无论代码应用何种方法加载,都无法拜访非公共库:System.loadLibrary(...)、DT_NEEDED 条目以及直接调用 dlopen(...) 都邑同样掉败。
对于各项更新,用户获得的应用体验应当是一致的,而开辟者应不必进行紧急更新应用以应对平台变革。是以,我们建议不要应用私有 C/C++ 符号。所有 Android 设备都必须经由过程的兼容性测试套件 (CTS) 并不包含对私有符号进行测试。词攀类符号可能不存在,也可能会采取不合的行动方法。这可能导致应用私有符号的应用在某些设备上,或在将来宣布的新版本体系中无法应用。当 Android 6.0 Marshmallow 大年夜 OpenSSL 切换到 BoringSSL 后,很多开辟者都发清楚明了这种问题。
为了削减这种过渡对用户的影响,我们肯定了 Google Play 上安装量最大年夜的应用中颇为常用且我们短期内仍可供给支撑的一些库(包含 libandroid_runtime.so、libcutils.so、libcrypto.so 和 libssl.so)。为了给您留出更多时光进行过渡,我们会临时支撑这些库;是以,如不雅看到表示您的代码在将来宣布的版本中会无效的警告信息,请立即竽暌硅以更正!
- $ readelf --dynamic libBroken.so | grep NEEDED
- 0x00000001 (NEEDED) Shared library: [libnativehelper.so]
- 0x00000001 (NEEDED) Shared library: [libutils.so]
- 0x00000001 (NEEDED) Shared library: [libstagefright_foundation.so]
- 0x00000001 (NEEDED) Shared library: [libmedia_jni.so]
- 0x00000001 (NEEDED) Shared library: [liblog.so]
- 0x00000001 (NEEDED) Shared library: [libdl.so]
- 0x00000001 (NEEDED) Shared library: [libz.so]
- 0x00000001 (NEEDED) Shared library: [libstdc++.so]
- 0x00000001 (NEEDED) Shared library: [libm.so]
- 0x00000001 (NEEDED) Shared library: [libc.so]
潜在问题:大年夜 API 24 开端,动态链接器将无法加载私有库,大年夜而导致应用无法加载。
解决筹划:重写本机代码,使其仅依附公共 API。短期解决筹划是:将没有复杂依存关系的平台库 (libcutils.so) 复制到项目;经久解决筹划是将相干代码复制到项目树。SSL/Media/JNI internal/binder API 不得经由过程本机代码拜访。须要时,本机代码应调用恰当的公共 Java API 办法。
推荐阅读
当我们启动一个App的时刻,Android体系会启动一个Linux Process,该Process包含一个Thread,称为UI Thread或Main Thread。平日一个应用的所有组件都运行在章一?Process中,当然,你可以>>>详细阅读
地址:http://www.17bianji.com/lsqh/34819.html
1/2 1