Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Studio 2.2 doesn't package third party library to apk

I use Android Studio 2.2's cmake to build native code, in the native code I invoked the ffmpeg api, so the ffmpeg library should be packaged. My CMakelists.txt is as below:

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)

In such case, I can make project successfully, but when I install the apk to emulator and run, it failed and show that "libavcodec-57.so" isn't found. Then I use tool (analyze apk) to check the apk, found that the ffmpeg library isn't packaged.

like image 698
tonyye Avatar asked Oct 06 '16 12:10

tonyye


1 Answers

I suffered the same problem. Gradle doesn't packaging .so files into apk while I filled CMakeLists.txt correctly, but finally I resolved it.

Add the JniLibs path into sourceSets in local build.gradle as this sample code: https://github.com/googlesamples/android-ndk/blob/master/hello-libs/app/build.gradle which is @Gerry mentioned in the comment.

I did:


  1. copy .so libraries into src/main/JniLibs/${ANDROID_ABI}.

    ex) mobile/src/main/JniLibs/armeabi-v7a/libavcodec.so


  1. edit 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
                   )

  1. in build.gradle (app)

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 {
    }
}

hope it helps you.

p.s. I used FFMPEG libraries that built myself.

like image 89
kugipark Avatar answered Sep 21 '22 11:09

kugipark