1.配置
下载ndk,cmake即可。
2.实现
MainActivity的实现
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}
/**
* jni调用java 静态方法
* @param msgFromJni jni中传过来的值
*/
public static void methodCalledByJni(String msgFromJni) {
Log.e("hxk", "methodCalledByJni,msg:" + msgFromJni);
}
/**
* jni调用java 非静态方法
* @param msgFromJni jni中传过来的值
*/
public void nostaticmethodCalledByJni(String msgFromJni) {
Log.e("hxk1", "nostaticmethodCalledByJnin,msg:" + msgFromJni);
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
native-lib.cpp的实现
#include <jni.h>
#include <string>
void callJavaMethod(JNIEnv *env,jobject thiz);
void callnotstaticJavaMethod(JNIEnv *env,jobject thiz);
using namespace std;
/**
* JNIEnv 表示一个指向jni环境的指针,可以通过它来访问jni提供的接口方法
* jobject 表示java对象中的this
* extern "C"的真实目的是实现类C和C++的混合编程。在C++源文件中的语句前面加上extern "C",表明它按照类C的编译和连接规约来编译和连接,而不是C++的编译的连接规约
*/
extern "C"
/**
* 被java调用的方法
* @param env 表示一个指向jni环境的指针,可以通过它来访问jni提供的接口方法
* @param thiz 表示java对象中的this
* @return
*/
JNIEXPORT jstring JNICALL
Java_com_example_asuper_jnitest_MainActivity_stringFromJNI(
JNIEnv *env,
jobject thiz) {
string hello = "test,Hello from C++";
//让其调用java中函数
callJavaMethod(env,thiz);
callnotstaticJavaMethod(env,thiz);
return env->NewStringUTF(hello.c_str());
}
/**
* 调用java中的静态方法
* @param env
* @param thiz
*/
void callJavaMethod(JNIEnv *env,jobject thiz) {
jclass clazz = env->FindClass("com/example/asuper/jnitest/MainActivity");
if (clazz == NULL) {
printf("find class MainActivity error!");
return;
}
jmethodID id = env->GetStaticMethodID(clazz,"methodCalledByJni","(Ljava/lang/String;)V");
if (id == NULL) {
printf("find method methodCalledByJni error!");
}
jstring msg = env->NewStringUTF("msg send by callJavaMethod in native-lib.cpp!");
env->CallStaticVoidMethod(clazz,id,msg);
}
/**
* 调用java中的非静态方法,非静态方法需要对象
*/
void callnotstaticJavaMethod(JNIEnv *env,jobject thiz) {
jclass clazz = env->FindClass("com/example/asuper/jnitest/MainActivity");
if (clazz == NULL) {
printf("find class MainActivity error!");
return;
}
jmethodID id = env->GetMethodID(clazz,"nostaticmethodCalledByJni","(Ljava/lang/String;)V");
if (id == NULL) {
printf("find method methodCalledByJni error!");
}
// jobject obj = env->NewObject(clazz,id);//报错,没结构体
jobject obj = thiz;//直接传java中的this对象
jstring msg = env->NewStringUTF("msg send by not static callJavaMethod in native-lib.cpp!");
env->CallVoidMethod(obj,id,msg);
}
log:
08-09 11:34:57.165 18196-18196/com.example.asuper.jnitest E/hxk: methodCalledByJni,msg:msg send by callJavaMethod in native-lib.cpp!
08-09 11:34:57.165 18196-18196/com.example.asuper.jnitest E/hxk1: nostaticmethodCalledByJnin,msg:msg send by not static callJavaMethod in native-lib.cpp!