Android ·

Android JNI的简单使用

JNI(java native interface)是一种java与其他语言交互的接口,在Android中一般是用来与c/c++进行交互。在Android开发中有很多的地方都会用到JNI技术,之前有用过JNI技术但是一直没有做个备忘,下面我就用Android Studio下面简单的使用JNI技术。

一:首先我们新建一个TestJniApplication工程。

如图:

在app/src/main/java下面创建一个名叫jni.test包,然后在里面新建一个名叫JniTest的类。并且声明一个返回String类型native方法。

二:使用javac生成class文件。

打开CMD,cd进入JniTest.java文件夹下面。运行javac JniTest生成class文件。 这样在此目录中就生成了一个JniTest.class的文件。也可以使用Android Studio生成,build->make project同样会在app/build/intermediates/classes/debug/jni/test/中自动生成JniTest.class文件。如图:

三:使用javah命名生成.h文件。

注意:不能在app/src/main/java/jni/test/目录中执行javah命令,这样会有异常。

使用javah -help可以知道class的名字必须是全报名+class名字。因此我们cd退到java目下执行javah jni.test.JniTest就可以成功在java目录中生成一个名叫:jni_test.JniTest.h的文件。打开文件可以看到生成的函数名字: JNIEXPORT jstring JNICALL Java_jni_test_JniTest_sayHellWorld(JNIEnv *, jclass);

JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。

jstring是返回值对应java的String。

函数名:Java+包全名+类名+函数名。

JNIEnv:一个包含JVM接口的结构指针。

jclass:声明本地函数类的实例(对象)。 四:编写jni代码。

在main目录下创建一个jni的目录(否则无法生成),把刚才生成的jni_test_JniTest.h(可以修改文件的命名)文件copy到这个文件下。并且新建一个同名的cpp文件(不是必须)内容:

#include "jni.h"
#include "jni_test_JniTest.h"
JNIEXPORT jstring JNICALL Java_jni_test_JniTest_sayHellWorld(JNIEnv *env, jclass obj){

     return env->NewStringUTF("Hello From JNI!");
  }

在gradle的defaultConfig添加

ndk{
            moduleName "JniTest"         //生成的so名字
            abiFilters "armeabi", "armeabi-v7a", "x86"  //输出指定三种abi体系结构下的so库。目前可有可无。
        }

然后在studio菜单中执行Build->Make project。可能会报错:

Error:Execution failed for task ':app:compileDebugNdk'.
> Error: Your project contains C++ files but it is not using a supported native build system.
Consider using CMake or ndk-build integration with the stable Android Gradle plugin:
 https://developer.android.com/studio/projects/add-native-code.html
or use the experimental plugin:
 https://developer.android.com/studio/build/experimental-plugin.html.

这样你需要查看你的NDK路径的配置:local.properties中

ndk.dir=E:\Android\sdk\ndk-bundle(配置你的NDK路径,这里是我的)

再次你需要修改gradle.properties文件中添加:

android.useDeprecatedNdk=true //声明可以不使用最新的NDK

然后再Build->Rebuild project后就生成.so

然后把这三个文件copy到app/libs下,在JniTest类中加载库:

public class JniTest {
    static {
        System.loadLibrary("JniTest");//不用输入lib前缀和.so后缀
    }
    public static native String sayHellWorld();

}

在MainActivity中使用:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TextView textView = (TextView) findViewById(R.id.text);
        textView.setText(JniTest.sayHellWorld());
    }
}

运行程序就可以看到输出了。

参与评论