java打印Jni层log

  在eclipse上新建jni工程可以参考:http://www.cnblogs.com/ashitaka/p/5953708.html

要在java层打印c的log必须引入这个头文件的宏定义:

#ifndef __LOG
#define __LOG
#ifdef __cplusplus
extern "C" {
#endif
#include <android/log.h>
// 宏定义类似java 层的定义,不同级别的Log LOGI, LOGD, LOGW, LOGE, LOGF。 对就Java中的 Log.i log.d
#define LOG_TAG    "HelloJni" // 这个是自定义的LOG的标识
//#undef LOG // 取消默认的LOG
#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG, __VA_ARGS__)
#define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG, __VA_ARGS__)
#define LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG, __VA_ARGS__)
#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG, __VA_ARGS__)
#define LOGF(...)  __android_log_print(ANDROID_LOG_FATAL,LOG_TAG, __VA_ARGS__)

#ifdef __cplusplus
}
#endif
#endif

分析一下:这里调用了系统的log文件 #include <android/log.h>

#ifndef _ANDROID_LOG_H
#define _ANDROID_LOG_H

#include <stdarg.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * 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;

/*
 * Send a simple string to the log.
 */
int __android_log_write(int prio, const char *tag, const char *text);

/*
 * Send a formatted string to the log, used like printf(fmt,...)
 */
int __android_log_print(int prio, const char *tag,  const char *fmt, ...)
#if defined(__GNUC__)
#ifdef __USE_MINGW_ANSI_STDIO
#if __USE_MINGW_ANSI_STDIO
    __attribute__ ((format(gnu_printf, 3, 4)))
#else
    __attribute__ ((format(printf, 3, 4)))
#endif
#else
    __attribute__ ((format(printf, 3, 4)))
#endif
#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 abort 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, ...)
#if defined(__GNUC__)
    __attribute__ ((noreturn))
#ifdef __USE_MINGW_ANSI_STDIO
#if __USE_MINGW_ANSI_STDIO
    __attribute__ ((format(gnu_printf, 3, 4)))
#else
    __attribute__ ((format(printf, 3, 4)))
#endif
#else
    __attribute__ ((format(printf, 3, 4)))
#endif
#endif
    ;

#ifdef __cplusplus
}
#endif

#endif /* _ANDROID_LOG_H */
View Code

这里面定义了log的优先级,并且log最终调用的都是__android_log_print(...)函数:

int __android_log_print(int prio, const char *tag, const char *fmt, ...)  
{  
    va_list ap;  
    char buf[LOG_BUF_SIZE];  
   
    va_start(ap, fmt);  
    vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);  
    va_end(ap);  
   
    return __android_log_write(prio, tag, buf);  
}  

所以自己定义一个头文件,并且定义宏指令指向__android_log_print(...)。就可以调用了。

另外在 system/core/include/cutils/log.h 也有定义,但是有些没有,而且在#include <cutils/log.h>提示找不到。估计是版本变更了。但是原理是一样的。

下面是测试函数:

JNIEXPORT jint JNICALL Java_com_example_hellojni_MainActivity_test
  (JNIEnv *env, jclass clazz){
    LOGD("log.d Java_Log_test()");
    LOGI("Log.i Java_Log_test()");
    return 0;
}

安卓测试程序:

public class MainActivity extends Activity {
    
    static{
        System.loadLibrary("HelloJava");
    }
    private Button btn_getString;
    private TextView tv_content;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initUI();
        setEvent();
    }
    
    
    private void setEvent() {
        // TODO Auto-generated method stub
        btn_getString.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                tv_content.setText(getString());
                test();
            }
        });
    }


    private void initUI() {
        // TODO Auto-generated method stub
        btn_getString = (Button) findViewById(R.id.btn_getString);
        tv_content = (TextView) findViewById(R.id.tv_content);
    }


    public static native String getString();
    public static native int test();
}

测试结果:

参考博客:http://blog.csdn.net/thl789/article/details/6638494

     http://blog.csdn.net/luoshengyang/article/details/6581828

 

posted @ 2016-12-07 20:04  麦哈顿博士  阅读(1657)  评论(0编辑  收藏  举报