JNI中log 列印以及 NDK環境變數配置
阿新 • • 發佈:2019-01-06
1. 匯入log標頭檔案
在你使用的 .c/ .cpp 檔案中
匯入 log.h 標頭檔案
#include<Android/log.h>
加上
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