Android Studio 2.2 не упаковывает стороннюю библиотеку в apk
Я использую Android Studio 2.2 cmake
для создания собственного кода, в собственном коде я вызывал ffmpeg api, поэтому библиотека ffmpeg должна быть упакована. Мой CMakelists.txt
выглядит следующим образом:
cmake_minimum_required(VERSION 3.4.1)
include_directories(libs/arm/include)
link_directories(libs/arm/lib/)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
# Associated headers in the same location as their source
# file are automatically included.
src/main/cpp/native-lib.cpp )
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
add_library(avcodec-57 SHARED IMPORTED)
set_target_properties(avcodec-57 PROPERTIES IMPORTED_LOCATION C:/Users/tony/Desktop/MyApplication/app/libs/arm/lib/libavcodec-57.so)
target_link_libraries(native-lib avcodec-57)
target_link_libraries(native-lib avformat-57)
target_link_libraries(native-lib avutil-55)
target_link_libraries(native-lib avfilter-6)
В таком случае я могу сделать проект успешно, но когда я устанавливаю apk в эмулятор и запускаю, он не работает и показывает, что "libavcodec-57.so" не найден.
Затем я использую инструмент (анализ apk), чтобы проверить apk, обнаружил, что библиотека ffmpeg не упакована.
Ответы
Ответ 1
Я нашел способ, который работает для меня, но не уверен, что он поможет вам, но может. Я использую Android Studio 2.2, и столкнулся с вашей проблемой.
Я создал jar файл с предварительно созданными в нем библиотеками:
lib
--|armeabi
--|--|libMyLIb.so
etc.
просто создав папку lib с этим содержимым где-нибудь и выполнив команду
zip -r myjar.zip lib && mv myjar.zip myjar.jar
Затем я помещаю файл jar здесь:
app/libs/myjar.jar
И добавил эти строки в CMakeLists.txt, который создает собственную .so-библиотеку внутри Android Studio. То есть, я начал с пустого проекта с шаблона для вызовов на собственный код (по умолчанию libnative-lib.so):
# already there:
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib} )
# my addition:
add_custom_command(TARGET native-lib POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${PROJECT_SOURCE_DIR}/libs"
$<TARGET_FILE_DIR:native-lib>)
И волшебным образом, теперь, если я построю apk, содержимое моей банки в конечном итоге окажется в последнем apk. Не спрашивайте меня, почему это работает, на самом деле, я понятия не имею, это было случайно.
Что для меня значит, это то, что я компилирую пустой libnative-lib.so, только для того, чтобы обмануть Android Studio, включив мою банку.
Возможно, кто-то найдет более чистое решение и может указать, где мое решение - это смешной цикл, который возник из-за недопонимания gradle и cmake...
Ответ 2
У меня была такая же проблема.
Cmake не автоматически упаковывает третью библиотеку в apk, вы должны сделать это самостоятельно.
Вот пример libavcodec и libavutil из ffmpeg.
1- Скопируйте свой встроенный lib в приложение /libs/ [abi]/
Пример: app/libs/armeabi-v7a/libavcodec.so
2- Копировать в приложение /libs/include
Затем в вашем cmakelist.txt добавьте нужные библиотеки.
find_library( log-lib log )
set(ffmpeg_DIR ../../../../libs) #set path to libs folder
add_library( libavutil SHARED IMPORTED )
set_target_properties( libavutil PROPERTIES IMPORTED_LOCATION ${ffmpeg_DIR}/${ANDROID_ABI}/libavutil.so )
add_library( libavcodec SHARED IMPORTED )
set_target_properties( libavcodec PROPERTIES IMPORTED_LOCATION ${ffmpeg_DIR}/${ANDROID_ABI}/libavcodec.so )
include_directories(libs/include) #add include dir. don't know why ../ not needed
add_library( native-lib SHARED src/main/cpp/native-lib.cpp )
target_link_libraries( native-lib libavcodec libavutil ${log-lib} )
Наконец, в вашем файле build.gradle jniLibsfolder:
sourceSets.main {
jniLibs.srcDirs = ['libs']
}
Настройка jniLibs.srcDir была ключом для меня, чтобы иметь возможность связывать библиотеки lib в apk.
Обратите внимание, что я использовал папку libs, но вы, вероятно, можете использовать любую папку, в которой хотите сохранить ваши предварительно созданные библиотеки.
Нашел рабочий пример github (не мой): https://github.com/imchenjianneng/StudyTestCase
Ответ 3
У меня была та же проблема.
Gradle не упаковывает .so файлы в apk, когда я правильно заполнял CMakeLists.txt, но, наконец, я разрешил его.
Добавьте путь JniLibs в sourceSets в local build.gradle, как этот пример кода:
https://github.com/googlesamples/android-ndk/blob/master/hello-libs/app/build.gradle
который @Gerry упоминается в комментарии.
Я сделал:
- изменить CMakeLists.txt
CMakeLists.txt
cmake_minimum_required(VERSION 3.4.1)
# project path (absolute), change it to yours.
set(projectDir C:/Users/Administrator/AndroidStudioProjects/TestApp1)
# headers
include_directories(${projectDir}/mobile/src/main/JniLibs/${ANDROID_ABI}/include)
# sample ndk lib
add_library( native-lib SHARED src/main/cpp/native-lib.cpp )
# FFMPEG libraries
add_library( lib_avcodec SHARED IMPORTED )
set_target_properties( lib_avcodec PROPERTIES IMPORTED_LOCATION ${projectDir}/mobile/src/main/JniLibs/${ANDROID_ABI}/libavcodec.so)
# ...
# (omitted) same codes with lib_avdevice, lib_avfilter, lib_avformat, lib_avutil, lib_swresample, and lib_swscale each.
# ...
target_link_libraries( # Specifies the target library.
native-lib
lib_avcodec
lib_avdevice
lib_avfilter
lib_avformat
lib_avutil
lib_swresample
lib_swscale
)
- в build.gradle(приложение)
build.gradle
android {
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "your-application-Id"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags "-std=c++11 -frtti -fexceptions"
}
}
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
abiFilters 'armeabi', 'armeabi-v7a'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
# ADD THIS BLOCK.
sourceSets {
main {
// let gradle pack the shared library into apk
jniLibs.srcDirs = ['src/main/JniLibs']
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
productFlavors {
}
}
надеюсь, что это поможет вам.
p.s. Я использовал библиотеки FFMPEG, которые сами построили.