【问题标题】:Include Shared library .so in android studio在 android studio 中包含共享库 .so
【发布时间】:2016-08-02 16:48:31
【问题描述】:

我在 ndk 的源文件夹中提取了 ffmpeg,然后在那里编译它只是因为我遵循了这个:http://www.roman10.net/2013/08/18/how-to-build-ffmpeg-with-ndk-r9/ 并成功生成了带有 arm/libandroid 文件夹>arm/include 文件。

之后,我在 $NDK/sources/ffmpeg/android/arm 中创建了一个 Android.mk 文件,在我的 android 项目(src/main) 中创建了一个 Android.mk /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 并成功生成了带有 .so 文件的 jniLibs,但是在构建项目时我得到 libavcodec/avcodec.h: No such file or directory

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文件夹中可以吗?

【问题讨论】:

    标签: android android-studio ffmpeg android-ndk java-native-interface


    【解决方案1】:

    如果您自己使用 ndk-build,则无需从 gradle 编译任何内容。

    将您的 jni 源设置为不存在的文件夹或没有文件夹:

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

    并删除此块:

    // New code
    android.ndk {
        moduleName = "tutorial01"
    }
    

    【讨论】:

    • 如果我删除 android.ndk 在这种情况下,它无法查看其他默认标头,例如 jni.h 和 malloc 等。
    • 现在我使用 ndk-build form build.gradle 而不是命令行。
    • ndkBuild 任务是您的任务,调用 ndk-build。这不是 android 插件对 ndk-build 的内置调用。你说你能够生成你的 .so 文件,所以不清楚你的问题究竟发生在哪一步:构建 .so 文件,在 AS 中编辑代码,构建 APK...你能澄清一下吗?
    • 如果我在这种情况下构建我的项目,则使用上述设置 .so 文件会在 libs 文件夹中生成,但是当我尝试在我的 tutorial01.c 中使用它们的头文件时,我没有得到这样的文件或目录.(有关更多详细信息,我正在尝试使用 ffmpeg)。
    • 嘿,我更新了我的问题,更详细的请检查一下。
    【解决方案2】:

    我参考了第三方 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 中,并在 jni 文件夹中包含 .h 文件的文件夹并且不需要在android.ndk中添加-l,因为我已经在headers.srcDir中添加了(我只是在这里添加了提及)。

    所以我在这里用 repositories 完全替换了我的 Android.mk,它真的很简单。

    【讨论】:

      猜你喜欢
      • 2023-03-17
      • 2015-11-24
      • 1970-01-01
      • 2018-06-05
      • 2016-09-04
      • 1970-01-01
      • 2021-06-12
      • 2013-05-17
      相关资源
      最近更新 更多