如何在Android Studio中从.so文件调用功能/方法

时间:2018-10-17 02:02:17

标签: android android-studio android-ndk java-native-interface .so

我正在尝试在我的Android应用中实现ffmpeg。 我已经有了需要的预构建的 .so 文件。

我只是不知道如何调用库中的众多功能之一。 到目前为止,这是我所拥有的:

我已将每个 .so 文件放置在jniLibs文件夹下 enter image description here

这是我的gradle文件 Here is my gradle file

从那里,我像这样加载库:

static {
    Log.e("jni", "starting");
    System.loadLibrary("avdevice");
    Log.e("jni", "finished");
}

加载成功。到目前为止,一切都很好。

接下来,我查看.h文件以查找可以调用的方法。请注意,我假设此.h文件已捆绑到.so文件中。这可能就是一切崩溃的地方。

/**
* Return the LIBAVDEVICE_VERSION_INT constant.
*/

unsigned avdevice_version(void);

由于我现在知道需要调用的方法名称,因此将其放在代码中:

public native int avdeviceVersion();

当我尝试致电avdeviceVersion();时,我收到此错误消息:

java.lang.UnsatisfiedLinkError: No implementation found for int com.my.app.ApplicationContext.avdeviceVersion() (tried Java_com_my_app_ApplicationContext_avdeviceVersion and Java_com_my_app_ApplicationContext_avdeviceVersion__)

现在,我意识到Java_com_my_app_ApplicationContext_avdeviceVersion与.h文件中的方法名称不匹配。但是,我一无所知,如何使其与之匹配,以及下一步该怎么做。如果您知道,请尽可能详尽地说明。假设我什么都不知道:)

更新

我添加了Android.mk文件和Application.mk,还添加了一个名为video.c的Jni桥。

JNIEXPORT jint JNICALL Java_com_my_app_jni_VideoKit_version(JNIEnv *env, jobject instance, jobjectArray args) {
return (*env)->avdevice_version();}

我的Android.mk是这样的:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := avdevice
LOCAL_SRC_FILES := video.c
include $(BUILD_SHARED_LIBRARY)

有了这些更改,结果是相同的。

1 个答案:

答案 0 :(得分:0)

您应该配置使用c / c ++类的环境。 您需要CMakeLists.txt或Android.mk / Application.mk。

然后,您应该创建一个用于链接Java类和本机类的类。

This link可以为您提供帮助。

如错误消息所述, 需要jint Java_{PACKAGE_NAME}_{CLASS_NAME}_{FUNCTION_NAME}(JNIEnv *env, jobject obj)。您可以在函数内部调用avdevice_version()

更新

在Android.mk中,首先创建预构建的共享库,然后进行链接共享库

include $(CLEAR_VARS)
LOCAL_MODULE := static_avdevice # you can change the name
LOCAL_SRC_FILES = avdevice.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include # header file directory
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include # header file directory
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := jniLinker
LOCAL_SRC_FILES := video.c
LOCAL_STATIC_LIBRARIES := static_avdevice
include $(BUILD_SHARED_LIBRARY)

然后,加载库。 System.loadLibrary("jniLinker");

而且,googlesamples github中有很多示例。 https://github.com/googlesamples/android-ndk/tree/master/hello-libs 这是使用3rd-party库的代码示例。 (但它使用CMake。)