当先锋百科网

首页 1 2 3 4 5 6 7

   在jni的c、c++文件输出本地log首先要引入ndk的log.h头文件,文件在ndk目录的 \android-ndk-r13b-windows-x86_64\android-ndk-r13b\platforms\android-24\arch-x86\usr\include\android中。

打开头文件可以看到定义了一个枚举的log优先级和具体打印log的方法

/*
 * Android log priority values, in ascending priority order.
 */
typedef enum android_LogPriority {
    ANDROID_LOG_UNKNOWN = 0,
    ANDROID_LOG_DEFAULT,    /* only for SetMinPriority() */
    ANDROID_LOG_VERBOSE,
    ANDROID_LOG_DEBUG,
    ANDROID_LOG_INFO,
    ANDROID_LOG_WARN,
    ANDROID_LOG_ERROR,
    ANDROID_LOG_FATAL,
    ANDROID_LOG_SILENT,     /* only for SetMinPriority(); must be last */
} android_LogPriority;

/*
 * 输出一个简单字符串log 参数:log优先级, log标志,log内容
 */
int __android_log_write(int prio, const char *tag, const char *text);

/*
 * 输出一个格式字符串的log,用法同printf
 */
int __android_log_print(int prio, const char *tag,  const char *fmt, ...)
#if defined(__GNUC__)
    __attribute__ ((format(printf, 3, 4)))
#endif
    ;

/*
 * A variant of __android_log_print() that takes a va_list to list
 * additional parameters.
 */
int __android_log_vprint(int prio, const char *tag,
                         const char *fmt, va_list ap);

/*
 * Log an assertion failure and SIGTRAP the process to have a chance
 * to inspect it, if a debugger is attached. This uses the FATAL priority.
 */
void __android_log_assert(const char *cond, const char *tag,
			  const char *fmt, ...)    


具体使用:

a、引入log.h头文件

#include <android/log.h>

b、调用方法输出log

__android_log_print(ANDROID_LOG_DEBUG, “MyLog“, "Hello jni , test log....");


通过定义宏减少重复代码的使用,如下代码:

#include <jni.h>
#include <string>
#include <android/log.h>
// Log标记
#define  LOG_TAG "MyLog"
// 各个优先级的宏定义
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_write(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)




#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jstring JNICALL
Java_com_aidesudi_testjni_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {
    std::string hello = "Hello from C++";

    // 直接调试方式输出
    __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "Hello jni , test log....");
 
    // 通过定义宏输出
    LOGV("Print the log V ");
    LOGE("Print the log ERROR : %s",hello.c_str());
    LOGI("Print the log INFO : %d", 12345);
    LOGW("Pring the log WARN ");
    LOGD("Pring the log DEBUG :%s","Test print log");

    return env->NewStringUTF(hello.c_str());
}


#ifdef __cplusplus
}
#endif


运行代码可以在控制看到如下log信息,大大方便jni代码的调试;



当然也可以将上面定义的宏放在一个头文件中,做为一个公用的头文件可以在不同项目或多个c/c++文件中使用,比如:mylog.h

#ifndef TESTJNI_MYLOG_H
#define TESTJNI_MYLOG_H

#include <android/log.h>
// Log标记
#define  LOG_TAG "MyLog"
// 各个优先级的宏定义
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGW(...) __android_log_write(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)

#endif //TESTJNI_MYLOG_H

使用的时候直接引入 mylog.h 头文件,#include "mylog.h"  然后直接调用具体优先级log输出方法即可。