所以我提供二进制文件作为打包为aar
的远程依赖项。android 库在src/main/jniLibs/<abi>/
目录中有libMyLibrary.so
文件,因此在构建和部署时,它们位于 aar 的 jni 目录中。该库唯一的其他东西是一个清单文件,只包含包名称package.name.A
different.package.B
package.name.A
作为对不同项目的依赖项导入会导致所有内容在构建中正确打包,并且共享库包含在调试/发布 APK 的lib/<abi>/libMyLibrary.so
中。但是,安装时不会将它们提取到应用程序的本机目录中。
实际安装的apk显示.so
文件存在于apk中,ZipFile(context.applicationInfo.sourceDir).getEntry("lib/${Build.SUPPORTED_ABIS[0]}/libMyLibrary.so")
工作,我可以以这种方式提取它(只是不是应用程序的nativeDir,安全异常)。System.mapLibraryName("MyLibrary")
返回"libMyLibrary.so"...
在我将它们作为远程依赖项提供之前,它们已被提取,并包含在应用程序的src/main/jniLibs/<abi>/
目录中。现在,我可以让它提取,同时通过aar
将它们作为远程依赖项提供的唯一方法是包含在清单android:extractNativeLibs="true"
中。
如何正确提取内容,而无需在我的清单中声明?
我需要在远程库的清单中声明一些内容,以便在合并时,Android 知道共享的本机库并且它会正确提取?我需要 Android.mk 文件吗?
指导/帮助将不胜感激!
这个答案对 extractNativeLibs 功能的使用进行了相当详细的描述,以及如何更改打包/部署过程才能将其设置为 false:https://stackoverflow.com/a/44704840/13924538。 tl;DR:您的APK将是一个更大的下载,但加载速度更快,占用手机的整体空间更少,因为它不需要解压缩。
extractNativeLibs的文档在这里,它也提供了一些见解: https://developer.android.com/guide/topics/manifest/application-element#extractNativeLibs
如果设置为 false,则您的原生库必须与页面对齐,并以未压缩的形式存储在 APK 中。
下面是 zipalign 工具的文档,您可以手动运行该工具,也可以在部署(预签名)过程中与 shell 脚本合并: https://developer.android.com/studio/command-line/zipalign
zipalign [-f] [-v] 4 infile.apk outfile.apk # f overwrites outfile.apk, v for verbose, 4 byte is the only allowed value that does anything for alignment
或者,在 Gradle 中,在签名步骤之前:
task zipAlign {
workingDir "<my apk output dir>"
commandLine "zipalign -f -v 4 infile.apk outfile.apk"
}
添加到different.package.B
的build.gradleandroid
块
compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 }
解决了我的问题。通过aar
提供的 *.so 文件现在提取到应用程序的本机目录。
参见:https://github.com/05nelsonm/TOPL-Android-TorBinary