使用Android studio3.0开发的,不需要创建对应的native方法的.h文件。定义完了native方法后,就可以在cpp文件中使用就可以了。
1.自定义log打印
#include <android/log.h>
#define TAG "NDKProject"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , TAG , __VA_ARGS__);
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG , __VA_ARGS__);
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , TAG , __VA_ARGS__);
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , TAG , __VA_ARGS__);
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL , TAG , __VA_ARGS__);
2.创建一个类,里面加载对应的cpp库和定义相应的成员。
public class Native {
companion object {
init {
System.loadLibrary("native-lib")
}
}
/**
* A native method that is implemented by the 'native-lib' n
* which is packaged with this application.
*/
external fun stringFromJNI(): String
/**
* 在native层读写文件
*/
external fun upDateFile(file_path: String): Void
external fun upDateString(): String
external fun upDataIntArray(array: IntArray): IntArray
//定义被jni调用的native方法
external fun JNICallJava():Void
//普通方法供jni调用
public fun loadMessage(data: String){
printMessage(data)
}
private fun printMessage(data: String){
// println(data);
Log.i("TAG" , data);
}
}
3.对应的cpp文件内容:
#include <jni.h>
#include <string>
#include <android/log.h>
#define TAG "NDKProject"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG , TAG , __VA_ARGS__);
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO , TAG , __VA_ARGS__);
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN , TAG , __VA_ARGS__);
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR , TAG , __VA_ARGS__);
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL , TAG , __VA_ARGS__);
using namespace std;
extern "C" JNIEXPORT jstring
JNICALL
Java_com_myself_ndkproject_Native_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
extern "C" JNIEXPORT void
JNICALL
Java_com_myself_ndkproject_Native_upDateFile(JNIEnv *env, jclass jclass, jstring path) {
const char *file_path = env->GetStringUTFChars(path, NULL);
if (file_path == NULL) {
return;
}
FILE *file = fopen(file_path, "a+");
if (file == NULL) {
return;
}
char data[] = "I'm a body";
int count = fwrite(data, strlen(data), 1, file);
fclose(file);
env->ReleaseStringUTFChars(path, file_path);
}
extern "C" JNIEXPORT jstring
JNICALL
Java_com_myself_ndkproject_Native_upDateString(JNIEnv *env , jboolean jclass ){
std::string upDate = "upDateString from c";
return env->NewStringUTF(upDate.c_str());
}
/**操作数组的两种方式:
* 1.生成native层的数组拷贝。
* 2.调用数组指针进行操作。
*/
extern "C" JNIEXPORT jintArray
JNICALL
Java_com_myself_ndkproject_Native_upDataIntArray(JNIEnv *env , jclass jclass , jintArray jarray){
/*jint jniArray[5];
jint leng = env->GetArrayLength(jarray);
env->GetIntArrayRegion(jarray , 0 , leng , jniArray);
for (int i = 0; i < leng; ++i) {
jniArray[i] += 5;
LOGI("I = %d" , jniArray[i]);
}
env->SetIntArrayRegion(jarray , 0 , leng , jniArray);*/
//得到数组的指针
jint* data = env->GetIntArrayElements(jarray , NULL);
//得到数组的长度
jsize leng = env->GetArrayLength(jarray);
for (int i = 0; i < leng; ++i) {
data[i] += 3;
LOGI("*I = %d" , data[i]);
}
//释放数组资源和数组指针
env->ReleaseIntArrayElements(jarray , data , 0);
return jarray;
}
extern "C" JNIEXPORT void
JNICALL
Java_com_myself_ndkproject_Native_JNICallJava(JNIEnv *env , jclass jclass1){
//获取类
jclass cls_native = env->FindClass("com/myself/ndkproject/Native");
if (cls_native == NULL){
return;
}
//获取loadMessage静态方法:第三个参数是方法的ID
jmethodID methodID = env->GetMethodID(cls_native , "loadMessage" , "(Ljava/lang/String;)V");
if (methodID == NULL){
return;
}
//找到对应的构造方法
jmethodID structure = env->GetMethodID(cls_native , "<init>" , "()V");
if (structure == NULL){
return;
}
//得到类的实例
jobject native_class = env->NewObject(cls_native , structure , NULL);
if (native_class == NULL){
return;
}
//调用相对用的普通方法
jstring str = env->NewStringUTF("call instance method");
env->CallVoidMethod(static_cast<_jclass *>(native_class), methodID , str);
env->DeleteGlobalRef(cls_native);
env->DeleteGlobalRef(reinterpret_cast<jobject>(methodID));
env->DeleteGlobalRef(reinterpret_cast<jobject>(structure));
env->DeleteGlobalRef(native_class);
env->DeleteGlobalRef(str);
}