搭建NDK工程的时候特别要注意踩坑,平时基本没玩过NDK的东西,第一次搭建FFmpeg的环境就被坑爹了

不知道从Android studio哪个版本开始,创建native c++的项目“CMakeLists.txt”文件就被放在src/main/cpp文件夹下了,以前最早的工程这个文件是被放在app路径下的(跟build.gradle是同一级)。

搭建FFmpeg的环境,需要在Linux环境下编译FFmpeg库

一、FFmpeg最新的搭建

将FFmpeg的lib库和头文件全部放在src/main/cpp路径下

android studio giraff android studio giraffe_cmake


开始书写CmakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

#定义一个FFmpeg文件路径
set(FFMPEG ${CMAKE_SOURCE_DIR}/ffmpeg)
#头文件所在文件
include_directories(${FFMPEG}/include)
#需要传递的编译路径
set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} -L${FFMPEG}/libs/${CMAKE_ANDROID_ARCH_ABI}")
#指定编译路径,会将src路径下所有的c文件都编到native-lib中
file(GLOB src_files *.cpp)

add_library( # Sets the name of the library.
             native-lib

             SHARED

             ${src_files}
             #native-lib.cpp
        )


find_library( # Sets the name of the path variable.
              log-lib
              log )

target_link_libraries( # Specifies the target library.
                       native-lib
                       avcodec avfilter avformat avutil swresample swscale
                       ${log-lib}
                       #z
        )

最后配置build.gradle

externalNativeBuild {
            cmake {
                cppFlags ""
                abiFilters "armeabi-v7a"
            }
        }

        ndk{
            abiFilters("armeabi-v7a")
        }

这里需要注意,上面ndk{}这个必须要配置,否则就会在apk运营起来闪退,会报如下的错误

Process: com.dh.dh_ndkproject3, PID: 3175
    java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.dh.dh_ndkproject3-LeqHzP9jyBW7bHn3tzU9tg==/base.apk"],nativeLibraryDirectories=[/data/app/com.dh.dh_ndkproject3-LeqHzP9jyBW7bHn3tzU9tg==/lib/arm64, /system/lib64, /product/lib64]]] couldn't find "libnative-lib.so"
        at java.lang.Runtime.loadLibrary0(Runtime.java:1012)
        at java.lang.System.loadLibrary(System.java:1672)
        at com.dh.dh_ndkproject3.MainActivity.<clinit>(MainActivity.java:12)
        at java.lang.Class.newInstance(Native Method)
        at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:69)
        at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:41)
        at android.app.Instrumentation.newActivity(Instrumentation.java:1224)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3340)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3614)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
        at android.os.Handler.dispatchMessage(Handler.java:112)
        at android.os.Looper.loop(Looper.java:216)
        at android.app.ActivityThread.main(ActivityThread.java:7625)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
2020-06-22 00:56:26.033 3175-3252/com.dh.dh_ndkproject3 E/MemoryLeakMonitorManager: MemoryLeakMonitor.jar is not exist!
2020-06-22 00:56:26.034 3175-3290/com.dh.dh_ndkproject3 E/AwareLog: AtomicFileUtils: readFileLines file not exist: android.util.AtomicFile@3e4b40a
2020-06-22 00:56:26.038 3175-3290/com.dh.dh_ndkproject3 E/AwareLog: AtomicFileUtils: readFileLines file not exist: android.util.AtomicFile@f7e47b

然后就是配置CMakeList.txt的路径,是在创建NDK项目的时候自动生成的,最新的配置和老的配置有所不同,如果需要改成老的配置,这里的路径就需要自己手动修改,老的配置下面会讲。

externalNativeBuild {
        cmake {
            //cmake文件的路径,以前cmake是放在app一个等级的
            path "src/main/cpp/CMakeLists.txt"
            //cmake的版本
            version "3.10.2"
        }
    }

二、FFmpeg老的搭建套路

此时FFmpeg的lib库和头文件就不是全部放在src/main/cpp下了,而是将库文件放在app下的libs中,

头文件仍然放在src/main/cpp中

android studio giraff android studio giraffe_android_02

开始书写CmakeLists.txt,此时的cmake文件就跟最新的文件写法有所差别,这两部分是同一个文件,
因为这个代码块不够智能把“/*.cpp”当成注释的开始了,┭┮﹏┭┮,所以才故意分开的

cmake_minimum_required(VERSION 3.4.1)

#指定编译路径
file(GLOB SOURCE src/main/cpp/*.cpp)
add_library( # Sets the name of the library.
             native-lib

             SHARED

             ${SOURCE}
             #src/main/cpp/native-lib.cpp
        )

#编译时候的头文件
include_directories(src/main/cpp/include)
#将armeabi-v7a设置为环境路径
set(mylib ${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI})
#需要传递的编译路径
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${mylib}")

find_library( # Sets the name of the path variable.
              log-lib

              log )

target_link_libraries( # Specifies the target library.
                       native-lib
                       #指定哪些静态库需要编译到native-lib中
                       avcodec avfilter avformat avutil swresample swscale
                       ${log-lib} )

build.gradle的配置,ndk的配置参考上面最新的配置套路,唯一需要修改的是将CMakeList.txt的路径配置路径修改到app下。

externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
            version "3.10.2"
        }
    }

哎 纪念被坑过的时间,伤不起