ndk是什么
- jni是java和C交互到接口。
- ndk是利用jni,将C编译成so库,并将库和Apk进行打包的工具。
- ndk本质是使用jni,但有提供了便于操作到打包工具。
Android Studio编写C++,增加代码提示
添加ndk插件
ndk程序实例
- java调用C代码。
- C代码调用java中的method。
- C代码使用java中的属性。
TestJni.java
public class TestJni {
private static final String TAG = "TestJni";
private int numInJava;
//加载库
static {
System.loadLibrary("native-lib");
}
public TestJni() {
numInJava = 50;
}
public void setMethodByNative(int value){
Log.i(TAG, "setMethodByNative value: "+value);
Log.i(TAG, "setMethodByNative numInJava: "+numInJava);
}
public static void setStaticByNative(int value){
Log.i(TAG, "setStaticByNative: "+value);
}
//java调用C中的方法
public native void nativeInit();
//C调用java中的方法
public native void nativeExecution();
public native void nativeStaticExecution();
}
通过javah,生成头文件(详见: https://tonybi.blog.csdn.net/article/details/118163597)
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_ch43testcpp_jni_TestJni */
#ifndef _Included_com_example_ch43testcpp_jni_TestJni
#define _Included_com_example_ch43testcpp_jni_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_ch43testcpp_jni_TestJni
* Method: nativeInit
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_ch43testcpp_jni_TestJni_nativeInit
(JNIEnv *, jobject);
/*
* Class: com_example_ch43testcpp_jni_TestJni
* Method: nativeExecution
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_ch43testcpp_jni_TestJni_nativeExecution
(JNIEnv *, jobject);
/*
* Class: com_example_ch43testcpp_jni_TestJni
* Method: nativeStaticExecution
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_ch43testcpp_jni_TestJni_nativeStaticExecution
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
实现该头文件
#include <jni.h>
#include <string>
#include <android/log.h>
#include "com_example_ch43testcpp_jni_TestJni.h"
//使用android log
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , "TestJni", __VA_ARGS__)
jclass mClass;
jobject mObject;
jmethodID mStaticMethodId, mnotStaticMethodId;
jfieldID mNumInJavaId;
/*
* Class: com_example_ch43testcpp_jni_TestJni
* Method: nativeInit
* Signature: ()V
*/
extern "C" JNIEXPORT void JNICALL Java_com_example_ch43testcpp_jni_TestJni_nativeInit
(JNIEnv *env, jobject thiz)
{
jclass clazz = env->GetObjectClass(thiz);
//获取类
mClass = (jclass)env->NewGlobalRef(clazz);
//获取类对象
mObject = env->NewGlobalRef(thiz);
//获取类中的方法
mStaticMethodId = env->GetStaticMethodID(mClass, "setStaticByNative", "(I)V");
mnotStaticMethodId = env->GetMethodID(mClass, "setMethodByNative", "(I)V");
//获取类的属性
mNumInJavaId = env->GetFieldID(mClass, "numInJava", "I");
}
/*
* Class: com_example_ch43testcpp_jni_TestJni
* Method: nativeExecution
* Signature: ()V
*/
extern "C" JNIEXPORT void JNICALL Java_com_example_ch43testcpp_jni_TestJni_nativeExecution
(JNIEnv *env, jobject thiz)
{
env->CallVoidMethod(mObject, mnotStaticMethodId, 100);
int num = (int)env->GetIntField(mObject, mNumInJavaId);
LOGI("num=%d", num);
num = 10;
}
/*
* Class: com_example_ch43testcpp_jni_TestJni
* Method: nativeStaticExecution
* Signature: ()V
*/
extern "C" JNIEXPORT void JNICALL Java_com_example_ch43testcpp_jni_TestJni_nativeStaticExecution
(JNIEnv *env, jobject thiz)
{
env->CallStaticVoidMethod(mClass, mStaticMethodId, 200);
}