1. 导入log头文件
在你使用的 .c/ .cpp 文件中
导入 log.h 头文件
#include<Android/log.h>
2.在android.mk 中
加上
LOCAL_LDLIBS :=-llog
注意Android.mk里有一行include $(CLEAR_VARS)
必须把LOCAL_LDLIBS :=-llog放在它后面才有用,
否则相当于没写。
3. 定义LOG 函数
先定义一个全局变量,再定义一些输出的LOG函数:
#define LOG_TAG "HelloJni"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG ,__VA_ARGS__) // 定义LOGD类型
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG ,__VA_ARGS__) // 定义LOGI类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG ,__VA_ARGS__) // 定义LOGW类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG ,__VA_ARGS__) // 定义LOGE类型
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG ,__VA_ARGS__) // 定义LOGF类型
上述代码中定义的函数
分别对应于Android 的Java代码中的
Log.d(), Log.i(), Log.w(),Log.e(), Log.f()等方法.
4.举例 一定要注意打印的时候使用C++的打印方法
之前
LOGD("haigui###### number = %d",number);
JNIEXPORT void JNICALL Java_com_example_hellojni_HelloJni_sayHello
(JNIEnv *env, jobject obj){
//获取obj中对象的class对象
jclass clazz = env->GetObjectClass(obj);
//获取Java中的number字段的id(最后一个参数是number的签名)
jfieldID id_number = env->GetFieldID(clazz,"number","I");
//获取number的值
jint number = env->GetIntField(obj,id_number);
LOGD("haigui###### number = %d",number);
//修改number的值为100,这里要注意的是jint对应C++是long类型,所以后面要加一个L
env->SetIntField(obj,id_number,100L);
}
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := HelloJni
LOCAL_SRC_FILES := HelloJni.cpp
LOCAL_LDLIBS +=-llog
#LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
linux下ndk配置:
在etc/profile 文件末尾追加 两行
export NDK_HOME=/home/denghaigui/AndroidDevTool/android-ndk-r10e
export PATH=$NDK_HOME:$PATH
配置完成后 source /etc/profile
注意多次source 会让/home/denghaigui/AndroidDevTool/android-ndk-r10e 重复添加 重复添加后 项目也会找不到ndk路径 ndk也没法编译
所以只要source一次就可以了 当source多次后 重启机子就能恢复正常
eg:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>
#define LOG_TAG "HelloJni"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG ,__VA_ARGS__) // 定义LOGD类型
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG ,__VA_ARGS__) // 定义LOGI类型
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG ,__VA_ARGS__) // 定义LOGW类型
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG ,__VA_ARGS__) // 定义LOGE类型
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG ,__VA_ARGS__) // 定义LOGF类型
#ifndef _Included_com_example_hellojni_HelloJni
#define _Included_com_example_hellojni_HelloJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_hellojni_HelloJni
* Method: getString
* Signature: ()Ljava/lang/String;
* java调用C++中方法
*/
JNIEXPORT jstring JNICALL Java_com_example_hellojni_HelloJni_getString
(JNIEnv *env, jobject obj){
env->GetObjectClass(obj);
return env->NewStringUTF("Hello from JNI !");
}
/*
* Class: com_example_hellojni_HelloJni
* Method: sayHello
* Signature: ()V
* C++改变java属性的值
*/
//JNIEXPORT void JNICALL Java_com_example_hellojni_HelloJni_sayHello
// (JNIEnv *env, jobject obj){
// //获取obj中对象的class对象
// jclass clazz = env->GetObjectClass(obj);
// //获取Java中的number字段的id(最后一个参数是number的签名)
// jfieldID id_number = env->GetFieldID(clazz,"number","I");
// //获取number的值
// jint number = env->GetIntField(obj,id_number);
// LOGD("haigui###### number = %d",number);
// //修改number的值为100,这里要注意的是jint对应C++是long类型,所以后面要加一个L
// env->SetIntField(obj,id_number,100L);
//}
/*
* Class: com_example_hellojni_HelloJni
* Method: sayHello
* Signature: ()V
* C++中调用java父函数和子函数
*/
JNIEXPORT void JNICALL Java_com_example_hellojni_HelloJni_sayHello
(JNIEnv *env, jobject obj){
//获取obj中对象的class对象
jclass clazz = env->GetObjectClass(obj);
//获取Java中的father字段的id(最后一个参数是father字段的签名)对应HelloJni.java中 public Father father = new Child(); father对象
jfieldID id_father = env->GetFieldID(clazz,"father","Lcom/example/hellojni/Father;");
//获取father字段的对象
jobject father = env->GetObjectField(obj,id_father);
//获取father对象的class对象
jclass clazz_father = env->FindClass("com/example/hellojni/Father");
//获取father对象中的function方法的id
jmethodID id_father_function = env->GetMethodID(clazz_father,"function","()V");
//调用父类中的function方法(但是会执行子类的方法)
env->CallVoidMethod(father,id_father_function);
//调用父类中的function方法(执行就是父类中的function方法)
env->CallNonvirtualVoidMethod(father,clazz_father,id_father_function);
}
/*
* Class: com_example_hellojni_HelloJni
* Method: maxCallback
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_example_hellojni_HelloJni_maxCallback
(JNIEnv *env, jobject obj){
//获取obj中对象的class对象
jclass clazz = env->GetObjectClass(obj);
//获取Java中的max方法的id(最后一个参数是max方法的签名)
jmethodID id_max = env->GetMethodID(clazz,"max","(DD)D");
//调用max方法
jdouble doubles = env->CallDoubleMethod(obj,id_max,1.2,3.4);
//输出返回值
LOGD("haigui###### double = %f",doubles );
int i = 0;
LOGD("haigui ########## i = %d", i);
}
#ifdef __cplusplus
}
#endif
#endif