zoukankan      html  css  js  c++  java
  • 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

    这个只不过是自己的流水账,偶尔有一些心得,错误的地方概不负责
  • 相关阅读:
    基于sshpass批量实现主机间的key验证脚本
    一键安装mysql5.7.30脚本
    centos8网卡名称修改
    mysql分库备份脚本
    centos一键二进制编译安装mariadb-10.2.31脚本
    chrony时间同步服务简介及配置
    linux基于key验证
    expect 脚本语言中交互处理常用命令
    shell中数值测试和算术表达式比较
    JAVA Math的简单运用
  • 原文地址:https://www.cnblogs.com/ashitaka/p/6142521.html
Copyright © 2011-2022 走看看