jni
作为 java
代码与c/c++
代码之间的桥梁,通过jni
可以实现java
代码和c/c++
代码互相调用
在 jni新手笔记一 中已经可以通过ndk
编译生成libhello.so
文件
其中hello.h
文件中定义了一个简单的方法 getHello()
,这里简单演示下如何通过jni
实现java
代码调用c++
代码
一、新建native
方法
java
代码调用c/c++
代码需要通过native
方法,创建native
方法之后,使用native
方法所在类生成jni
头文件,java
代码调用native
方法将会通过jni
调用实现这个头文件的c/c++
源文件,通过这种方式就实现了java
代码调用c/c++
代码
新建类文件NDKTest.java
,在类文件中声明native
方法getHello()

生成jni
头文件需要中间文件NDKTest.class
,所以运行Build->Make Project
,在build
目录下找到NDKTest.class
文件,不同版本的Android Studio
生成的.class
文件的路径不一样,但都会在build
目录下

在
terminal
中进入classes
目录下,通过javah -jni
命令生成jni
头文件
运行 javah -jni com.don.ndk.NDKTest
,成功之后会得到头文件 com_don_ndk_NDKTest.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_don_ndk_NDKTest */
#ifndef _Included_com_don_ndk_NDKTest
#define _Included_com_don_ndk_NDKTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_don_ndk_NDKTest
* Method: getHello
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_don_ndk_NDKTest_getHello
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
生成的方法名为Java_com_don_ndk_NDKTest_getHello
,但是参数有 3 个,分别是 JNIEnv
,jobject
,jint
,这其中第三个参数jint
对应着java
代码中 getHello
函数的参数(int count)
;前两个值是固定的,JNIEnv
表示java环境
,这个值很重要,可以说我们在jni
的实现离不了它;jobject
表示当前的调用对象,在这里就是NDKTest
的一个实例
二、调用c++代码
将第一步生成的头文件com_don_ndk_NDKTest.h
放到ndk
目录下并新建ndktest.cpp
实现该头文件

在ndktest.cpp
调用hello.h
中的getHello()
方法
需要强调一点的是,在调用native
方法之前需要保证对应的so
加载成功,在上一篇中配置的so
库名字为hello
,在java
类NDKTest
中加载so
hello
package com.don.ndk;
public class NDKTest {
static {
System.loadLibrary("hello");
}
public native String getHello(int count);
}
MainActivity
中调用 getHello
方法
package com.don.ndk;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.text);
NDKTest ndkTest = new NDKTest();
mTextView.setText(ndkTest.getHello(6));
}
}
编译运行app
,可以看到屏幕上显示 hello
网友评论