学网站建设要多长时间,天河网站建设哪里好,设计品牌企业logo,wordpress必要的插件Android NDK开发详解之针对中间件供应商的建议 选择 API 级别和 NDK 版本使用 STL在 AAR 中分发原生库包含 JNI 库的 Java 中间件 分发使用 NDK 构建的中间件会引发其他问题#xff0c;但应用开发者无需对此感到担心。预构建库会为用户提供一些实现选项。
选择 API 级别和 ND… Android NDK开发详解之针对中间件供应商的建议 选择 API 级别和 NDK 版本使用 STL在 AAR 中分发原生库包含 JNI 库的 Java 中间件 分发使用 NDK 构建的中间件会引发其他问题但应用开发者无需对此感到担心。预构建库会为用户提供一些实现选项。
选择 API 级别和 NDK 版本
您的用户无法使用低于您的级别的 minSdkVersion。如果用户的应用需要在 API 21 上运行您就无法针对 API 24 构建应用。您可以针对低于用户级别的 API 级别构建库。您可以针对 API 16 构建应用并保持与 API 21 用户兼容。
各个 NDK 版本大部分是相互兼容的但版本间的变更偶尔也会破坏兼容性。如果您确定您的所有用户使用的都是相同版本的 NDK那么您最好也使用与用户相同的版本。否则请使用最新版本。
使用 STL
如果您正在编写 C 和使用 STL并且要分发共享库那么您在 libc_shared 和 libc_static 之间的选择会对您的用户产生影响。如果您要分发共享库则必须使用 libc_shared或确保共享库不会公开 libc 的符号。要实现此目标最好的方法是通过版本脚本明确声明您的 ABI 界面这也有助于将实现细节保持私有状态。例如一个简单的算术库可能拥有以下版本脚本 注意如果您要分发静态库无论是选择静态 STL 还是共享 STL 都无关紧要因为静态库中未关联任何内容。用户可以关联他们在应用中选择的任何内容。但用户必须关联一些内容即使是针对仅限 C 的使用方。因此请务必将这一点记录为必须采取的措施并记录用于构建的 NDK 版本以防 STL 版本之间存在不兼容的情况。 LIBMYMATH {
global:add;sub;mul;div;# C symbols in an extern block will be mangled automatically. See# https://stackoverflow.com/a/21845178/632035 for more examples.extern C {pow(int, int);}
local:*;
};首选方式应为版本脚本因为这是控制符号可见性的最可靠方式。这对于所有共享库无论是否是中间件来说都是最佳做法因为这可以防止您的实现细节被公开并能够缩短加载时间。
另一个可靠性较低的方式是在关联时使用 -Wl,–exclude-libs,libc_static.a -Wl,–exclude-libs,libcabi.a。这种方式的可靠性较低是因为它只会隐藏库中明确指定的符号并且不会为未使用的库报告诊断信息库名称中的拼写错误不属于错误并且用户应负责及时更新库列表。此方式也不会隐藏您自己的实现细节。
在 AAR 中分发原生库
注意本部分将介绍如何将 C/C API 分发给用户。如果原生库属于您的 Java API 的实现细节请参阅包含 JNI 库的 Java 中间件部分。
Android Gradle 插件可以导入在 AAR 中分发的原生依赖项。如果您的用户使用的是 Android Gradle 插件这将是他们使用您的库的最简单的方式。
原生库可以通过 AGP 打包到 AAR 中。如果您的库已经通过 externalNativeBuild 构建这便是最简单的方法。
非 AGP build 可以使用 ndkports或按照 Prefab 文档中的说明执行手动打包以便创建 AAR 的 prefab/ 子目录。
包含 JNI 库的 Java 中间件
包含 JNI 库即包含 jniLibs 的 AAR的 Java 库需要小心谨慎地处理这样它们包含的 JNI 库才不会与用户应用中的其他库发生冲突。例如如果 AAR 包含的 libc_shared.so 版本不同于应用使用的 libc_shared.so 版本那么只有其中一个版本会安装到 APK并且这可能会引发不可靠的行为。 警告错误 141758241较旧版本的 Android Gradle 插件目前不会诊断这种错误。系统将任意选择一个同名库打包到 APK 中。
最可靠的解决方案是确保 Java 库中的 JNI 库不超过一个这个建议也适用于应用。包括 STL 在内的所有依赖项都应静态关联到实现库并且应通过版本脚本强制执行 ABI 界面。例如包含 JNI 库 libfooimpl.so 的 Java 库 com.example.foo 应使用以下版本脚本
LIBFOOIMPL {
global:JNI_OnLoad;
local:*;
};本示例按照 JNI 提示中所述的说明在 JNI_OnLoad 中使用 registerNatives 来确保尽量少公开 ABI 界面并最大限度缩短库的加载时间。