需要 3 步:

Step1 把 .so file 放到 Android Studio project 正确的路径中

需要新建一个名为 jniLibs 文件夹,根据目标机器的 CPU-ABI 类型,把 .so file 放入对应的路径下:

weiyi$ cd app/src/main/
weiyi$ tree -L 2
.
├── AndroidManifest.xml
├── java
├── jniLibs
│   ├── armeabi
│   │   └── libhello-jni.so
│   └── armeabi-v7a
│       └── libhello-jni.so
└── res

至于在其它编译器(eclipse等)中的路径,以及 armeabiarmeabi-v7a 的解释,参考 StackOverflow - System.loadLibrary(…) couldn't find native library in my case

.so file 需要通过 NDK tool 编译 c/c++ 得到,可以从 android.googlesource.com 下载 libhello-jni.so

Step2 加载 .so library 并声明 native method

Java 端实现加载 .so library:(HelloJni.java)

package com.example.hellojni;

public class HelloJni {
    public native String stringFromJNI();

    static {
        System.loadLibrary("hello-jni");
    }
}

这篇开发文档 Developer - Sample: hello-jni 解释了 native 关键字。

Step3 最后就可以调用 .so library native method 了

类似调用任何一个类的方法:

    HelloJni helloJni = new HelloJni();
    LOGD(TAG, helloJni.stringFromJNI());
`

可以看到 log:Hello from JNI !。而整个工程目录应该是这样:

weiyiWorkCell:main weiyi$ tree -L 5
.
├── AndroidManifest.xml
├── java
│   └── com
│       ├── example
│       │   └── hellojni
│       │       └── HelloJni.java
├── jniLibs
│   ├── armeabi
│   │   ├── libhello-jni.so
│   └── armeabi-v7a
│       ├── libhello-jni.so
└── res

UnsatisfiedLinkError: No implementation found

在 step2 时,假如把 native method 声明在了一个随意命名的 package 或者随意命名的 java file 内,比如 com.example.hellojni21.HelloJni,你会遇到如下 exception:

java.lang.UnsatisfiedLinkError:
No implementation found for java.lang.String com.example.hellojni21.HelloJni.stringFromJNI() tried
Java_com_example_hellojni21_HelloJni_stringFromJNI and
Java_com_example_hellojni21_HelloJni_stringFromJNI__

这是因为命名存在一个默认的规则。 .so file 需要通过 NDK tool 编译 c/c++ 得到,c/c++ 实现 native method 时,要按如下规则命名,以 libhello-jni.so 为例:

jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env, jobject thiz )
规则如下:
Java_package_file_method(...)

所以,Java 端的包名、文件名、方法名就被规定好了,包名必须是 com_example_hellojni,文件名必须是 HelloJni,native method 声明必须是 String stringFromJNI()

这篇开发文档 Developer - Sample: hello-jni 描述了命名规则。

我们还可以通过命令行列出 shared library 中的方法:

weiyi$ nm -D libhello-jni.so
00000b90 T Java_com_example_hellojni_HelloJni_stringFromJNI

参考: