我使用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库没有打包。
答案 0 :(得分:3)
我发现了一种对我有用的方法,不确定它会对你有所帮助,但可能会有所帮助。我使用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
并将这些行添加到在Android Studio中构建本机.so-library的CMakeLists.txt中。也就是说,我从模板中的一个空项目开始调用本机代码(默认的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,我的jar的内容最终会在最后的apk中出现。不要问我为什么会这样,真的,我不知道,这是偶然的。
这对我来说意味着我编译空的libnative-lib.so,其唯一目的是诱骗Android Studio包含我的jar。
也许有人找到了一个更清洁的解决方案,并且可以指出我的解决方案是由于误解gradle和cmake导致的荒谬循环...
答案 1 :(得分:2)
我遇到了完全相同的问题。 Cmake不会自动将第三个库打包到apk中,你必须自己动手。
以下是来自ffmpeg的libavcodec和libavutil的例子。
1-将预先构建的lib复制到app / libs / [abi] /
例如:app/libs/armeabi-v7a/libavcodec.so
2-复制包含到app / 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
答案 2 :(得分:1)
我遇到了同样的问题。 当我正确填充CMakeLists.txt时,Gradle没有将.so文件打包到apk中,但最后我解决了它。
将JniLibs路径添加到本地build.gradle中的sourceSets中,如以下示例代码: https://github.com/googlesamples/android-ndk/blob/master/hello-libs/app/build.gradle 这是评论中提到的@Gerry。
我做了:
将.so库复制到src / main / JniLibs / $ {ANDROID_ABI}。
ex)mobile / src / main / JniLibs / armeabi-v7a / libavcodec.so
的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
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库。