Включить общую библиотеку .so в андроид студию

1

Я извлек ffmpeg из исходной папки ndk, а затем скомпилировал его там только для этого: http://www.roman10.net/2013/08/18/how-to-build-ffmpeg-with-ndk-r9/ и успешно сгенерировал android с файлами arm/lib и arm/include.

После этого я создал один файл Android.mk в $NDK/sources/ffmpeg/android/arm и один Android.mk в моем проекте Android (src/main/jni).

Мой src/main/jni/Android.mk выглядит следующим образом:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := tutorial01
LOCAL_SRC_FILES := tutorial01.c
LOCAL_LDLIBS := -llog -ljnigraphics -lz
LOCAL_SHARED_LIBRARIES := libavcodec

include $(BUILD_SHARED_LIBRARY)
$(call import-module,ffmpeg-3.0.1/android/arm)

и $NDK/sources/ffmpeg/android/arm/Android.mk:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE:= libavcodec
LOCAL_SRC_FILES:= lib/libavcodec-57.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

Я обновил свой build.gradle, как этот, и успешно сгенерировал jniLib с .so файлами, но я получаю libavcodec/avcodec.h: Нет такого файла или каталога при создании проекта.

import org.apache.tools.ant.taskdefs.condition.Os

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.2"

        defaultConfig.with {
            applicationId = "com.example.spartan.hello"
            minSdkVersion.apiLevel = 18
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = "1.0"
        }
    }
    android.buildTypes {
        release {
            minifyEnabled = false
            proguardFiles.add(file('proguard-android.txt'))
        }
    }

    android.sources {
        main {
            jni {
                source {
                    srcDirs = []
                }

            }

        }

        main {
            jniLibs {
                source {
                    srcDirs = ['src/main/libs']
                }
            }
        }

    }

    android.ndk {
        moduleName = "tutorial01"
        stl = 'gnustl_shared'
    }
}


task ndkBuild(type: Exec) {
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        commandLine 'ndk-build.cmd', '-C', file('src/main').absolutePath
    } else {
        commandLine 'ndk-build', '-C', file('src/main').absolutePath
    }
}
tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn ndkBuild
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
}

и загружать их в мою деятельность следующим образом:

static {
        System.loadLibrary("tutorial01");     
        System.loadLibrary("avcodec-57");   
    }

Я новичок в NDK, так ли это нормально, если мы вручную вставляем файлы заголовков в папку jni?

Теги:
ffmpeg
android-studio
android-ndk
jni

2 ответа

1
Лучший ответ

Я взял ссылку со стороннего образца Google https://github.com/googlesamples/android-ndk/tree/master/hello-thirdparty, который в основном предназначен для static lib (.a) и именно так я решил свою проблему с экспериментальным плагином gradle:

Мой файл build.gradle:

apply plugin: 'com.android.model.application'

model {
    android {
        compileSdkVersion = 23
        buildToolsVersion = "23.0.2"

        defaultConfig.with {
            applicationId = "com.example.spartan.hello"
            minSdkVersion.apiLevel = 18
            targetSdkVersion.apiLevel = 23
            versionCode = 1
            versionName = "1.0"
        }
    }
    android.buildTypes {
        release {
            minifyEnabled = false
            proguardFiles.add(file('proguard-android.txt'))
        }
    }

    repositories {
        libs(PrebuiltLibraries) {
            libavcodec {
                headers.srcDir "/home/spartan/AndroidStudioProjects/Hello/app/src/main/jni/include"
                binaries.withType(SharedLibraryBinary) {
                    sharedLibraryFile = file("/home/spartan/AndroidStudioProjects/Hello/app/src/main/jniLibs/${targetPlatform.getName()}/libavcodec-57.so")
                }
            }                

        }
    }

    android.ndk {
        moduleName = "tutorial01"

        def jniPath = "/home/spartan/AndroidStudioProjects/Hello/app/src/main/jniLibs"
        cppFlags.add("-I${file(jniPath)}".toString())
        file(jniPath).eachDirRecurse { dir ->
            cppFlags.add("-I${file(dir)}".toString())
        }
        ldLibs.addAll(["log", "android","jnigraphics"])
        stl = "gnustl_shared"
    }


    android.sources {
        main {
            jni {
                dependencies {
                    library "libavcodec" linkage "shared"
                }
            }
        }
    }

    android.productFlavors {
        create ("armv7") {
            ndk.abiFilters.add("armeabi-v7a")
        }
    }

    android.sources {
        main {
            jni {
                source {
                    srcDirs = ['src/main/none']
                }

            }

        }
    }

}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.1'
}

В моем случае я скопировал .so в jniLibs и включил папку .h в папку jni и нет необходимости добавлять -l в android.ndk, потому что я уже добавил в headers.srcDir (я просто добавил сюда, чтобы упомянуть).

Итак, я грамотно заменил Android.mk репозитарии и это действительно просто.

0

Если вы используете ndk-build самостоятельно, вам не нужно ничего компилировать из gradle.

Установите источники jni в несуществующую папку или нет папки:

android.sources{
   main.jni {
    source {
        srcDirs = [] // or ['src/main/none']
    }
  }
}

и удалите этот блок:

// New code
android.ndk {
    moduleName = "tutorial01"
}
  • 0
    Если я удалю android.ndk в этом случае, он не сможет выглядеть как другие заголовки по умолчанию, такие как jni.h, malloc и т. Д.
  • 0
    Теперь я использую ndk-build форму build.gradle не из командной строки.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню