老式打印
在jni开发的过程中如果打印封装的好,是能够很大的提高我们的开发效率,在之前的开发过程中一直网上寻找的代码,只做了简单的封装,只能System.out.println()方法一样简单的打印日志。打印的代码如下:
#ifndef CLOUD_LOG_H
#define CLOUD_LOG_H
#define NDK_LOG true
#if NDK_LOG
#include <android/log.h>
#include <jni.h>
#endif
#define TAG "ndk"
#if NDK_LOG
#define log_print_verbose(fmt, ...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, fmt, __VA_ARGS__)
#define log_print_debug(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, TAG, fmt, __VA_ARGS__)
#define log_print_info(fmt, ...) __android_log_print(ANDROID_LOG_INFO, TAG, fmt, __VA_ARGS__)
#define log_print_warn(fmt, ...) __android_log_print(ANDROID_LOG_WARN, TAG, fmt, __VA_ARGS__)
#define log_print_error(fmt, ...) __android_log_print(ANDROID_LOG_ERROR, TAG, fmt, __VA_ARGS__)
#else
#define log_print_verbose(fmt, ...) printf(fmt, ##__VA_ARGS__)
#define log_print_debug(fmt, ...) printf(fmt, ##__VA_ARGS__)
#define log_print_info(fmt, ...) printf(fmt, ##__VA_ARGS__)
#define log_print_warn(fmt, ...) printf(fmt, ##__VA_ARGS__)
#define log_print_error(fmt, ...) printf(fmt, ##__VA_ARGS__)
#endif
#define LOGV(fmt, ...) log_print_verbose(fmt, ##__VA_ARGS__)
#define LOGD(fmt, ...) log_print_debug(fmt, ##__VA_ARGS__)
#define LOGI(fmt, ...) log_print_info(fmt, ##__VA_ARGS__)
#define LOGW(fmt, ...) log_print_warn(fmt, ##__VA_ARGS__)
#define LOGE(fmt, ...) log_print_error(fmt, ##__VA_ARGS__)
#endif //CLOUD_LOG_H
新式打印
最新在UVCCamera项目中发现封装的打印方法比较好用,所以在这里记录下来,打印包含所在的类跟行等信息,很方便定位和查找问题,打印的效果如下:
2020-05-08 09:24:50.389 29170-29255/com.serenegiant.usbcameratest2 W/libUVCCamera: [29255*UVCPreview.cpp:211:setFrameCallback]:UVCPreview::setFrameCallback: 1,*************
2020-05-08 09:24:50.389 29170-29255/com.serenegiant.usbcameratest2 W/libUVCCamera: [29255*UVCPreview.cpp:223:setFrameCallback]:UVCPreview::setFrameCallback: 5,*************
2020-05-08 09:24:50.389 29170-29255/com.serenegiant.usbcameratest2 W/libUVCCamera: [29255*UVCPreview.cpp:247:setFrameCallback]:UVCPreview::setFrameCallback: 8,*************
2020-05-08 09:24:50.389 29170-29255/com.serenegiant.usbcameratest2 W/libUVCCamera: [29255*UVCPreview.cpp:254:setFrameCallback]:UVCPreview::setFrameCallback: 10,*************
该打印封装一共包含两个文件:utilbase.h,localdefines.h。
localdefines.h内容如下
#ifndef LOCALDEFINES_H_
#define LOCALDEFINES_H_
#include <jni.h>
#ifndef LOG_TAG
#define LOG_TAG "libUVCCamera"
#endif
#define LIBUVC_HAS_JPEG
// write back array that got by getXXXArrayElements into original Java object and release its array
#define ARRAYELEMENTS_COPYBACK_AND_RELEASE 0
// write back array that got by getXXXArrayElements into origianl Java object but do not release its array
#define ARRAYELEMENTS_COPYBACK_ONLY JNI_COMMIT
// never write back array that got by getXXXArrayElements but release its array
#define ARRAYELEMENTS_ABORT_AND_RELEASE JNI_ABORT
#define THREAD_PRIORITY_DEFAULT 0
#define THREAD_PRIORITY_LOWEST 19
#define THREAD_PRIORITY_BACKGROUND 10
#define THREAD_PRIORITY_FOREGROUND -2
#define THREAD_PRIORITY_DISPLAY -4
#define THREAD_PRIORITY_URGENT_DISPLAY -8
#define THREAD_PRIORITY_AUDIO -16
#define THREAD_PRIORITY_URGENT_AUDIO -19
#define USE_LOGALL // If you don't need to all LOG, comment out this line and select follows
//#define USE_LOGV
//#define USE_LOGD
#define USE_LOGI
#define USE_LOGW
#define USE_LOGE
#define USE_LOGF
#ifdef NDEBUG
#undef USE_LOGALL
#endif
#ifdef LOG_NDEBUG
#undef USE_LOGALL
#endif
// Absolute class name of Java object
// if you change the package name of UVCCamera library, you must fix these
#define JTYPE_SYSTEM "Ljava/lang/System;"
#define JTYPE_UVCCAMERA "Lcom/serenegiant/usb/UVCCamera;"
//
typedef jlong ID_TYPE;
#endif /* LOCALDEFINES_H_ */
utilbase.h内容如下:
#ifndef UTILBASE_H_
#define UTILBASE_H_
#include <jni.h>
#ifdef __ANDROID__
#include <android/log.h>
#endif
#include <unistd.h>
#include <libgen.h>
#include "localdefines.h"
#define SAFE_FREE(p) { if (p) { free((p)); (p) = NULL; } }
#define SAFE_DELETE(p) { if (p) { delete (p); (p) = NULL; } }
#define SAFE_DELETE_ARRAY(p) { if (p) { delete [](p); (p) = NULL; } }
#define NUM_ARRAY_ELEMENTS(p) ((int) sizeof(p) / sizeof(p[0]))
#if defined(__GNUC__)
// the macro for branch prediction optimaization for gcc(-O2/-O3 required)
#define CONDITION(cond) ((__builtin_expect((cond)!=0, 0)))
#define LIKELY(x) ((__builtin_expect(!!(x), 1))) // x is likely true
#define UNLIKELY(x) ((__builtin_expect(!!(x), 0))) // x is likely false
#else
#define CONDITION(cond) ((cond))
#define LIKELY(x) ((x))
#define UNLIKELY(x) ((x))
#endif
// XXX assertはNDEBUGが定義されていたら引数を含めて丸ごと削除されてしまうので
// 関数実行を直接assertの引数にするとその関数はNDEBUGの時に実行されなくなるので注意
#include <assert.h>
#define CHECK(CONDITION) { bool RES = (CONDITION); assert(RES); }
#define CHECK_EQ(X, Y) { bool RES = (X == Y); assert(RES); }
#define CHECK_NE(X, Y) { bool RES = (X != Y); assert(RES); }
#define CHECK_GE(X, Y) { bool RES = (X >= Y); assert(RES); }
#define CHECK_GT(X, Y) { bool RES = (X > Y); assert(RES); }
#define CHECK_LE(X, Y) { bool RES = (X <= Y); assert(RES); }
#define CHECK_LT(X, Y) { bool RES = (X < Y); assert(RES); }
#if defined(USE_LOGALL) && defined(__ANDROID__) && !defined(LOG_NDEBUG)
#define LOGV(FMT, ...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGD(FMT, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGI(FMT, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGW(FMT, ...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGE(FMT, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGF(FMT, ...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGV_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGV(__VA_ARGS__) \
: (0) )
#define LOGD_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGD(__VA_ARGS__) \
: (0) )
#define LOGI_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGI(__VA_ARGS__) \
: (0) )
#define LOGW_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGW(__VA_ARGS__) \
: (0) )
#define LOGE_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGE(__VA_ARGS__) \
: (0) )
#define LOGF_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGF(__VA_ARGS__) \
: (0) )
#else
#if defined(USE_LOGV) && defined(__ANDROID__) && !defined(LOG_NDEBUG)
#define LOGV(FMT, ...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGV_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGV(__VA_ARGS__) \
: (0) )
#else
#define LOGV(...)
#define LOGV_IF(cond, ...)
#endif
#if defined(USE_LOGD) && defined(__ANDROID__) && !defined(LOG_NDEBUG)
#define LOGD(FMT, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGD_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGD(__VA_ARGS__) \
: (0) )
#else
#define LOGD(...)
#define LOGD_IF(cond, ...)
#endif
#if defined(USE_LOGI) && defined(__ANDROID__)
#define LOGI(FMT, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGI_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGI(__VA_ARGS__) \
: (0) )
#else
#define LOGI(...)
#define LOGI_IF(cond, ...)
#endif
#if defined(USE_LOGW) && defined(__ANDROID__)
#define LOGW(FMT, ...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGW_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGW(__VA_ARGS__) \
: (0) )
#else
#define LOGW(...)
#define LOGW_IF(cond, ...)
#endif
#if defined(USE_LOGE) && defined(__ANDROID__)
#define LOGE(FMT, ...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGE_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGE(__VA_ARGS__) \
: (0) )
#else
#define LOGE(...)
#define LOGE_IF(cond, ...)
#endif
#if defined(USE_LOGF) && defined(__ANDROID__)
#define LOGF(FMT, ...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, "[%d*%s:%d:%s]:" FMT, \
gettid(), basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#define LOGF_IF(cond, ...) \
( (CONDITION(cond)) \
? LOGF(__VA_ARGS__) \
: (0) )
#else
#define LOGF(...)
#define LOGF_IF(cond, ...)
#endif
#endif
#ifndef LOG_ALWAYS_FATAL_IF
#define LOG_ALWAYS_FATAL_IF(cond, ...) \
( (CONDITION(cond)) \
? ((void)__android_log_assert(#cond, LOG_TAG, ## __VA_ARGS__)) \
: (void)0 )
#endif
#ifndef LOG_ALWAYS_FATAL
#define LOG_ALWAYS_FATAL(...) \
( ((void)__android_log_assert(NULL, LOG_TAG, ## __VA_ARGS__)) )
#endif
#ifndef LOG_ASSERT
#define LOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ## __VA_ARGS__)
#endif
#ifdef LOG_NDEBUG
#ifndef LOG_FATAL_IF
#define LOG_FATAL_IF(cond, ...) ((void)0)
#endif
#ifndef LOG_FATAL
#define LOG_FATAL(...) ((void)0)
#endif
#else
#ifndef LOG_FATAL_IF
#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ## __VA_ARGS__)
#endif
#ifndef LOG_FATAL
#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
#endif
#endif
#define ENTER() LOGD("begin")
#define RETURN(code,type) {type RESULT = code; LOGD("end (%d)", (int)RESULT); return RESULT;}
#define RET(code) {LOGD("end"); return code;}
#define EXIT() {LOGD("end"); return;}
#define PRE_EXIT() LOGD("end")
#if defined(__ANDROID__) && (defined(USE_LOGALL) || defined(USE_LOGI)) && !defined(LOG_NDEBUG)
#define MARK(FMT, ...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "[%s:%d:%s]:" FMT, \
basename(__FILE__), __LINE__, __FUNCTION__, ## __VA_ARGS__)
#else
#define MARK(...)
#endif
#define LITERAL_TO_STRING_INTERNAL(x) #x
#define LITERAL_TO_STRING(x) LITERAL_TO_STRING_INTERNAL(x)
#define TRESPASS() \
LOG_ALWAYS_FATAL( \
__FILE__ ":" LITERAL_TO_STRING(__LINE__) \
" Should not be here.");
void setVM(JavaVM *);
JavaVM *getVM();
JNIEnv *getEnv();
#endif /* UTILBASE_H_ */