Sha*_*yaz 17 java-native-interface android opencv native image-processing
我正在使用min SDK构建一个Android应用程序15
,它使用的是OpenCV库.问题是当我构建apk时,它的大小超过60
MB而且不是很好.
我检查了应用程序文件,我可以看到的是,规模过大,由于libopencv_java3.so
在像所有架构文件amr64
,armeabi
,mips
,x86
等.
我只使用opneCv进行图像处理.这个库还有许多其他功能,如视频处理,3D图像,对象检测等等,我不需要在我的应用程序中使用
如果我删除所有这些文件并构建APK,那么大小将减少50 MB,但为了使这个应用程序工作,我需要安装OpenCVManager
来运行我的应用程序.
有什么方法可以减少我的apk大小?
或者只是提取OpenCV
我感兴趣的功能并.so
为这些功能创建?
您无法删除库libopencv_java3.so
,这是必需的.
有什么方法可以减少我的apk大小?
在不修改库的情况下libopencv_java3.so
,您可以为不同的体系结构构建多个apks,而不是打包平面APK.只有一个拱门libopencv_java3.so
将打包到您的拆分APK.例如,你可以使用下面的配置打造只为x86
,armeabi-v7a
且mips
架构在build.gradle
splits {
abi {
enable true
reset()
include "x86", "armeabi-v7a", "mips"
universalApk false
}
}
Run Code Online (Sandbox Code Playgroud)
有关通过拆分减少apk大小的更多信息,请参见此处.
或者只是从OpenCV中提取我感兴趣的功能并为这些功能创建.so?
当然是.建设过程opencv
完全定制.如果您已经知道如何为Android构建opencv,请直接转到步骤2.
opencv_build
opencv
刚刚克隆的根目录platforms/android/build_sdk.py --ndk_path $ANDROID_NDK_ROOT --sdk_path $ANDROID_SDK_ROOT ../opencv_build .
构建过程需要android
命令来构建apk,因此Android SDK工具版本必须少于25.3.0
,from 25.3.0
,android
命令已被删除.
假设上面的步骤1正常运行.我在这里armeabi-v7a
举个例子.
opencv_build/o4a/lib/armeabi-v7a
libopencv_java3.so
也在这个目录中从您需要的模块创建一个小版本共享库,例如
$ arm-linux-androideabi-gcc -shared -o libopencv_tiny.so --sysroot=$ANDROID_NDK_ROOT/platforms/android-9/arch-arm -Wl,--whole-archive libopencv_core.a libopencv_imgcodecs.a libopencv_imgproc.a -Wl,--no-whole-archive
$ du -h libopencv_tiny.so
5.2M libopencv_tiny.so
$ arm-linux-androideabi-strip --strip-unneeded libopencv_tiny.so
$ du -h libopencv_tiny.so
4.1M libopencv_tiny.so
$ du -h libopencv_java3.so
9.8M libopencv_java3.so
Run Code Online (Sandbox Code Playgroud)这个小版本包括core
,image codecs
并且image proc
带有一个大小的4.1M
条带,但完整版libopencv_java3.so
的大小为9.8M
.
我libopencv_tiny.so
只是为了方便而使用名称,您必须libopencv_java3.so
在项目中使用相同的名称.否则System.loadLibrary
在Java中找不到本机库.
对于您需要的其他架构,例如arm64-v8a
,执行相同的操作.
对我来说,alijandro回答第二个答案是最好的解决方案,但我陷入了困境.所以,我通过apk拆分解决了这个问题.您需要上传与平台相关的apk以及通用apk.It将是理想的,因为OpenCV不提供模块级别的添加依赖性.
如果平台不匹配,将下载Universal apk.这里有关于apk publishing mutiple apk的精美博客.您需要维护相同的应用程序ID,密钥库,相同的应用程序版本,但代码版本不同
第1步.为spk拆分添加gradle代码.包括要为其创建单独的apk的体系结构.
android{
//......
splits {
abi {
enable true
reset()
include "armeabi","armeabi-v7a",'arm64-v8a',"mips","x86","x86_64",'arm64-v8a'
universalApk true
}
}
}
Run Code Online (Sandbox Code Playgroud)
步骤2.为不同平台添加不同代码版本的代码.
android{
//......
}
ext.versionCodes = ['armeabi': 3, 'armeabi-v7a': 4, 'arm64-v8a': 5,
mips: 6, 'x86': 7, 'x86_64': 8]
import com.android.build.OutputFile
// For each APK output variant, override versionCode with a combination
// of ABI APK value * 1000 + defaultConfig.versionCode
android.applicationVariants.all { variant ->
// assign different version code for each output
variant.outputs.each { output ->
def abiFilter = output.getFilter(OutputFile.ABI)
def abiMultiplier = 0
if (abiFilter != null) {
abiMultiplier = project.ext.versionCodes.get(abiFilter)
}
output.versionCodeOverride =
abiMultiplier * 1000 + android.defaultConfig.versionCode
}
}
Run Code Online (Sandbox Code Playgroud)
例如,如果初始版本代码为1,则生成的代码将为:
armeabi -> 3001
armeabi-v7a -> 4001
arm64-v8a -> 5001
mips -> 6001
x86 -> 7001
x86_64 -> 8001
Run Code Online (Sandbox Code Playgroud)
你的Gradle代码就像这样.
android{
//......
splits {
abi {
enable true
reset()
include "armeabi","armeabi-v7a",'arm64-
v8a',"mips","x86","x86_64",'arm64-v8a'
universalApk true
}
}
ext.versionCodes = ['armeabi': 3, 'armeabi-v7a': 4, 'arm64-v8a': 5,
mips: 6, 'x86': 7, 'x86_64': 8]
import com.android.build.OutputFile
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
def abiFilter = output.getFilter(OutputFile.ABI)
def abiMultiplier = 0
if (abiFilter != null) {
abiMultiplier = project.ext.versionCodes.get(abiFilter)
}
output.versionCodeOverride =
abiMultiplier * 1000 + android.defaultConfig.versionCode
}
}
Run Code Online (Sandbox Code Playgroud)
现在你需要逐个在playstore上发布所有apk.
注意:发布时请确保保留所有平台和通用apk.