Как уменьшить размер apk для Android-приложения, которому требуется openCv lib (только для обработки изображений)
Я создаю приложение для Android с минимальным SDK 15
, которое использует библиотеку OpenCV. Проблема в том, что при сборке apk его размер превышает 60
МБ, что не очень хорошо.
Я проверил файл приложения и увидел, что его размер слишком велик из-за файла libopencv_java3.so
во всех архитектурах, таких как amr64
, armeabi
, mips
, x86
и т.д.
Я использую opneCv только для обработки изображений. Эта библиотека имеет много других функций, таких как обработка видео, 3D-изображения, обнаружение объектов и многое другое, что мне не нужно в моем приложении, как
Если я удалю все эти файлы и соберу APK, то размер уменьшится на 50 МБ, но чтобы это приложение работало, мне нужно установить OpenCVManager
для запуска моего приложения.
Есть ли способ уменьшить размер моего apk?
Или же можно просто извлечь из OpenCV
интересующую меня функцию и создать .so
для этих функций?
Ответы
Ответ 1
Для меня alijandro ответ на второй ответ был лучшим решением, но я застрял в этом процессе. Итак, я решил проблему apk split. Вам нужно загрузить apk, связанную с платформой, а также универсальный apk. Это было бы идеально, поскольку OpenCV не обеспечивает добавление зависимости на уровне модуля.
Universal apk будет загружен в случае, если платформа не соответствует. Вот хорошо написанный блог о apk публикации mutiple apk. Вам нужно поддерживать одинаковый идентификатор приложения, Keystore, ту же версию приложения, но другую версию кода
Шаг 1. Добавьте код градиента для разделения spk. Включите архитектуру, для которой вы хотите создать отдельный apk.
android{
//......
splits {
abi {
enable true
reset()
include "armeabi","armeabi-v7a",'arm64-v8a',"mips","x86","x86_64",'arm64-v8a'
universalApk true
}
}
}
Шаг 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
}
}
Например, если исходный код версии равен 1, то сгенерированные коды будут:
armeabi -> 3001
armeabi-v7a -> 4001
arm64-v8a -> 5001
mips -> 6001
x86 -> 7001
x86_64 -> 8001
Все вместе ваш код 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
}
}
Теперь вам нужно публиковать все apk на playstore по одному.
Примечание. Во время публикации убедитесь, что вы сохранили всю платформу и универсальный apk.
Ответ 2
Вы не можете удалить библиотеку 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
}
}
Более подробную информацию об уменьшении размера apk путем разделения смотрите здесь.
Или же можно просто извлечь из OpenCV интересующую меня функцию и создать .so для этих функций?
Да, конечно. Процесс сборки opencv
полностью настроен. Если вы уже знаете, как собрать opencv для Android, перейдите к шагу 2 напрямую.
шаг 1
- получить исходник opencv
- создать каталог
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
, из 25.3.0
, команда android
удалена.
шаг 2
Предположим, что шаг 1 выше работает правильно. Здесь я возьму armeabi-v7a
в качестве примера.
- Перейдите в каталог
opencv_build/o4a/lib/armeabi-v7a
- Вы найдете много *.a для различных модулей opencv, библиотека
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
Миниатюрная версия, включающая в себя core
, image codecs
и image proc
имеет размер 4.1M
после полосы, но полная версия libopencv_java3.so
имеет размер 9.8M
.
Я использую libopencv_tiny.so
в качестве имени просто для удобства, вы должны использовать то же имя libopencv_java3.so
в вашем проекте. В противном случае System.loadLibrary
в Java не может найти нативную библиотеку.
Для остальной части архитектуры вам нужно, например arm64-v8a
, сделать то же самое.
Ответ 3
Приведенные выше два ответа довольно полны, но на всякий случай, если вам нужно больше деталей и регуляторов настройки, найдите эту статью.
Ответ 4
Если он содержит больше размера ресурсов, используйте ниже код в вашем файле градиента. Он удаляет неиспользуемые ресурсы из проекта.
buildTypes {
release {
minifyEnabled true
shrinkResources true
}
}
Если вы хотите удалить неиспользуемый код, используйте методы 64K
LINK2
Вы также можете задать вопрос в OpenCV
Q/A сайт
Ответ 5
Как создать .so файлы из некоторых функций OpenCV в Windows 10?