java - 如何在 Android 代码中使用 .so 文件来使用本地方法

标签 java android eclipse android-ndk java-native-interface

我有 libmath.so 文件,其中包含本地方法。我需要在我的 android 代码中调用 native 方法。我创建了一个示例 android 应用程序并在 libs/armeabi 文件夹中添加了 libmath.so,然后运行“右键单击鼠标”-> Android 工具-> 添加 native 支持。现在,在应用程序的 jni 文件夹中创建了以下内容的文件。

Android.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := libmath
LOCAL_SRC_FILES := libmath.cpp
include $(BUILD_SHARED_LIBRARY)

libmath.cpp

#include <jni.h>

当我将项目作为 android 应用程序运行时,它在控制台中显示如下:-

17:58:41 **** Build of configuration Default for project math ****
"F:\\Vinay\\Softwares\\android-ndk-r10d\\ndk-build.cmd" all 
[armeabi] Compile++ thumb: math <= libmath.cpp
[armeabi] StaticLibrary  : libstdc++.a
[armeabi] SharedLibrary  : libmath.so
[armeabi] Install        : libmath.so => libs/armeabi/libmath.so
17:58:53 Build Finished (took 11s.695ms)

这是我加载库的代码:-

public class MathJni {
static {
    System.loadLibrary("math");
}
public native String calc(String paramString);

public static final MathJni math = new MathJni();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String s= math.calc("help");

    }

在运行 android 应用程序后,当我通过模拟器启动应用程序时,出现以下错误。

02-06 07:38:36.900: D/dalvikvm(831): Trying to load lib /data/app-lib/com.example.math-2/libmath.so 0xb3cd0848
02-06 07:38:36.900: D/dalvikvm(831): Added shared lib /data/app-lib/com.example.math-2/libmath.so 0xb3cd0848
02-06 07:38:36.910: D/dalvikvm(831): No JNI_OnLoad found in /data/app-lib/com.example.math-2/libmath.so 0xb3cd0848, skipping init
02-06 07:38:37.540: W/dalvikvm(831): No implementation found for native Lcom/example/math/MathJni;.calc:(Ljava/lang/String;)Ljava/lang/String;
02-06 07:38:37.540: D/AndroidRuntime(831): Shutting down VM
02-06 07:38:37.550: W/dalvikvm(831): threadid=1: thread exiting with uncaught exception (group=0xb3a20ba8)
02-06 07:38:37.570: E/AndroidRuntime(831): FATAL EXCEPTION: main
02-06 07:38:37.570: E/AndroidRuntime(831): Process: com.example.math, PID: 831
02-06 07:38:37.570: E/AndroidRuntime(831): java.lang.UnsatisfiedLinkError: Native method not found: com.example.math.MathJni.calc:(Ljava/lang/String;)Ljava/lang/String;
02-06 07:38:37.570: E/AndroidRuntime(831):  at com.example.math.MathJni.calc(Native Method)
02-06 07:38:37.570: E/AndroidRuntime(831):  at com.example.math.MainActivity.onCreate(MainActivity.java:16)

此错误的可能原因是什么。

最佳答案

如果您未编写任何 C++ 代码并且仅预构建 .so 文件以直接从 Java 使用,则不必使用 NDK。

只需将 .so 文件放入您的项目中,在 libs/<abi> 下对于 eclipse 项目 - 在 jniLibs/<abi> 下对于 gradle 项目。

在这里,您所做的是创建一个内容几乎为空的 libmath NDK 模块。当您构建项目时,NDK 生成了一个新的 libmath.so 文件,其中没有您的初始库中的任何内容。所以删除你所有的 jni 文件和文件夹,将你以前的 .so 文件复制回 libs/<abi> ,然后再次运行您的项目。

如果您遇到其他问题,请验证您的 libmath.so 是否实现了 jstring com_example_math_MathJni_calc(JNIEnv* env, jobject* obj) ,或者检查您应该在 Java 端声明哪些内容以使用您的库,并使用正确的包名称和签名(如果您的 .so 文件附带了一份文档,它应该说明这一点)。

关于java - 如何在 Android 代码中使用 .so 文件来使用本地方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28366263/

相关文章:

java - 为什么Java AQS队列会向后遍历

java - 格式化 JEditorPane 的光标、工具提示、链接

java - 如何在应用程序信息中添加选项(卸载更新)

创建大量对象的ArrayList时Java堆空间错误?

android - java.lang.IllegalArgumentException : This component requires that you specify a valid android:textAppearance attribute

android - IndexOutOfBoundsException setSpan (0 ... 1) 超出长度 0 结束

android - 从 Android 应用程序中的谷歌地图获取最近的公交车站

java - 如何从 WSDL 创建包含多个服务的 WebService?

java - 如何在 Eclipse Java 调试器中跟踪变量的值

android - 如何解决警告 : You are installing software that contain unsigned content and authenticity and validity of this software can not established