Android Studio JNI学习之(4)-日志框架

日志

    开发者不希望直接与logger内核模块进行交互,Android运行库提供了API调用一边Java和native向logger内核发送日志信息。native通过包含该头文件:


#include "android/log.h"

    除了添加头文件,还需要在Android,mk中添加库

..
LOCAL_LDLIBS :=  -L$(SYSROOT)/usr/lib -llog
...include $(BUILD_SHARED_LIBRARY)

    支持日志的优先级

typedef enum android_LogPriority {
    ...
    ANDROID_LOG_VERBOSE,
    ANDROID_LOG_DEBUG,
    ANDROID_LOG_INFO,
    ANDROID_LOG_WARN,
    ANDROID_LOG_ERROR,
    ANDROID_LOG_FATAL,
    ...
} android_LogPriority;


  日志函数

__android_log_write(ANDROID_LOG_WARN, "hello-jni", "warning log."); //生成简单的日志信息
__android_log_print(ANDROID_LOG_ERROR, "hello-jni", "Failed with error %s", "NullPointerException"); //生成格式化的日志信息
log_verbose("my name is %s, age %d", "eric", 27); //传递多个参数生产的日志信息,跟__android_log_print功能大致一样

void log_verbose(const char* format,...) {
    va_list args;
    va_start(args, format);
    __android_log_vprint(ANDROID_LOG_VERBOSE, "hello-jni", format, args);
    va_end(args);
}

    控制台日志打印结果:

  自定义日志管理类

//
// Created by liangjiangli on 2017/9/29.
// NDK基本日志框架
//

#include <android/log.h>

/*定义日志优先级*/

#define LOG_LEVEL_VERBOSE 1

#define LOG_LEVEL_DEBUG 2

#define LOG_LEVEL_INFO 3

#define LOG_LEVEL_WARNING 4

#define MLOG_LEVEL_ERROR 5

#define LOG_LEVEL_FATAL 6

#define LOG_LEVEL_SILENT 7



#ifndef LOG_TAG

#define LOG_TAG __FILE__

#endif



#ifndef LOG_LEVEL

#define LOG_LEVEL LOG_LEVEL_VERBOSE

#endif



#define LOG_NOOP (void) 0



#define LOG_PRINT(level,fmt,...) __android_log_print(level,LOG_TAG,"(%s:%u) %s: " fmt, __FILE__, __LINE__, __PRETTY_FUNCTION__, ##__VA_ARGS__)



#if LOG_LEVEL_VERBOSE >= LOG_LEVEL

#define LOG_VERBOSE(fmt,...) LOG_PRINT(ANDROID_LOG_VERBOSE,fmt,##__VA_ARGS__)

#else

#define LOG_VERBOSE(...) LOG_NOOP

#endif



#if LOG_LEVEL_DEBUG >= LOG_LEVEL

#define LOG_DEBUG(fmt,...) LOG_PRINT(ANDROID_LOG_DEBUG,fmt,##__VA_ARGS__)

#else

#define LOG_DEBUG(...) LOG_NOOP

#endif



#if LOG_LEVEL_INFO >= LOG_LEVEL

#define LOG_INFO(fmt,...) LOG_PRINT(ANDROID_LOG_INFO,fmt,##__VA_ARGS__)

#else

#define LOG_INFO(...) LOG_NOOP

#endif



#if LOG_LEVEL_WARNING >= LOG_LEVEL

#define LOG_WARNING(fmt,...) LOG_PRINT(ANDROID_LOG_WARN,fmt,##__VA_ARGS__)

#else

#define LOG_WARNING(...) LOG_NOOP

#endif



#if LOG_LEVEL_ERROR >= LOG_LEVEL

#define LOG_ERROR(fmt,...) LOG_PRINT(ANDROID_LOG_ERROR,fmt,##__VA_ARGS__)

#else

#define LOG_ERROR(...) LOG_NOOP

#endif



#if LOG_LEVEL_FATAL >= LOG_LEVEL

#define LOG_FATAL(fmt,...) LOG_PRINT(ANDROID_LOG_FATAL,fmt,##__VA_ARGS__)

#else

#define LOG_FATAL(...) LOG_NOOP

#endif



#if LOG_LEVEL_FATAL >= LOG_LEVEL

#define LOG_ASSERT(expression,fmt,...) if(!(expression)){__android_log_assert(#expression,LOG_TAG,fmt,##__VA_ARGS__);}

#else

#define LOG_ASSERT(...) LOG_NOOP

#endif

  更新Android.mk,定义日志标签以及日志等级

...
#动态链接日志库
LOCAL_LDLIBS :=  -L$(SYSROOT)/usr/lib -llog
#定义日志标签
LOG_TAG := \"hello-jni\"

#定义默认日志等级
ifeq ($(APP_OPTIM), release)
    LOG_LEVEL := LOG_LEVEL_SILENT
else
    LOG_LEVEL := LOG_LEVEL_VERBOSE
endif

#追加编译标记
LOCAL_CFLAGS += -DLOG_TAG=$(LOG_TAG)
LOCAL_CFLAGS += -DLOG_LEVEL=$(LOG_LEVEL)

include $(BUILD_SHARED_LIBRARY)

  APP_OTIM变量指定了构建类型是发布还是调试,基于APP_OTIM标识,将LOG_LEVEL设置成匹配的日志等级。

  最终在原生函数中应用如下:

#include "LogUtil.h"
...
JNIEXPORT jstring JNICALL Java_com_study_eric_jni_JniTest_getJniString
        (JNIEnv *env, jobject object) {
    LOG_VERBOSE("The stringFormJNI is called!");
    LOG_DEBUG("env=%p thiz=%p",env, object);
    LOG_INFO("Returning a new string");
    LOG_WARNING("Warning");
}


09-29 15:12:27.785 18542-18542/com.study.eric V/hello-jni: (/Users/daredos/Android/Study/app/src/main/jni/com_study_eric_JniTest.c:12) jstring Java_com_study_eric_jni_JniTest_getJniString(JNIEnv *, jobject): The stringFormJNI is called!
09-29 15:12:27.785 18542-18542/com.study.eric D/hello-jni: (/Users/daredos/Android/Study/app/src/main/jni/com_study_eric_JniTest.c:13) jstring Java_com_study_eric_jni_JniTest_getJniString(JNIEnv *, jobject): env=0xb4078be0 thiz=0xbe9b1d7c
09-29 15:12:27.785 18542-18542/com.study.eric I/hello-jni: (/Users/daredos/Android/Study/app/src/main/jni/com_study_eric_JniTest.c:14) jstring Java_com_study_eric_jni_JniTest_getJniString(JNIEnv *, jobject): Returning a new string
09-29 15:12:27.785 18542-18542/com.study.eric W/hello-jni: (/Users/daredos/Android/Study/app/src/main/jni/com_study_eric_JniTest.c:15) jstring Java_com_study_eric_jni_JniTest_getJniString(JNIEnv *, jobject): Warning



发布了18 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/LIANGJIANGLI/article/details/78130635