1:在编译so文件的c或cpp文件之前中加入以下代码,就可以在android中的log显示日志内容
      #include <android/log.h>
      #define LOG_TAG "show infomation"
      #define LOGW(a )  __android_log_write(ANDROID_LOG_WARN,LOG_TAG,a)
2:就可以在c或cpp中加入LOWG(str) 就可以在android中的log中显示打印的内容
3.这样写完以后,如果直接编译,就会报 __android_log_write 方法undefined.
怎么回事呢?关键是在设置编译选项上面。
在Android.mk文件里,可以指定一个LOCAL_LDLIBS的参数。如果不指定,那么编译的时候,只会引入默认的几个重要的lib,比如libc之类的。
如果要用log,那就要把 liblog给引进来。
网上很多的写法是 LOCAL_LDLIBS := -llog ,这在build static lib的时候没什么问题。如果是build shared lib,就会报个 cannot find -llog的错误。意思是找不到liblog.so这个库文件。
因此需要改成 LOCAL_LDLIBS :=  -L$(SYSROOT)/usr/lib -llog 才可以正常编译。
其中-L参数是指定了搜索lib的路径。
下面是一个android.mk的内容的例子:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := TestNdkNetwork
LOCAL_SRC_FILES := HttpConnection.cpp
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)

Android中Log信息的输出方法 收藏 
共两篇文章,第一篇讲述了如何在程序中输出Log信息,第二篇详细的分析了Log信息的输出机制。
下面是第一篇(转自:http://blog.163.com/binghaitao@126/blog/static/3383532520099309366435/) 
1:在编译so文件的c或cpp文件之前中加入以下代码,就可以在android中的log显示日志内容
      #include <android/log.h>
      #define LOG_TAG "show infomation"
      #define LOGW(a )  __android_log_write(ANDROID_LOG_WARN,LOG_TAG,a)
2:就可以在c或cpp中加入LOWG(str) 就可以在android中的log中显示打印的内容
3.这样写完以后,如果直接编译,就会报 __android_log_write 方法undefined.
怎么回事呢?关键是在设置编译选项上面。
在Android.mk文件里,可以指定一个LOCAL_LDLIBS的参数。如果不指定,那么编译的时候,只会引入默认的几个重要的lib,比如libc之类的。
如果要用log,那就要把 liblog给引进来。
网上很多的写法是 LOCAL_LDLIBS := -llog ,这在build static lib的时候没什么问题。如果是build shared lib,就会报个 cannot find -llog的错误。意思是找不到liblog.so这个库文件。
因此需要改成 LOCAL_LDLIBS :=  -L$(SYSROOT)/usr/lib -llog 才可以正常编译。
其中-L参数是指定了搜索lib的路径。
下面是一个android.mk的内容的例子:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := TestNdkNetwork
LOCAL_SRC_FILES := HttpConnection.cpp
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)

下面是第二篇(转自http://blog.csdn.net/knock/archive/2010/04/21/5511255.aspx)

为了调试,必须要将log怎么打印的搞清楚,于是有了以下的分析。
我们通常在程序中插入LOGD(..),LOGE(..)之类的语句,但什么情况下可以查看这些打印消息呢?
首先,来到定义处:system/core/include/cutils/log.h,在开头就可以看到
#ifndef LOG_TAG
#define LOG_TAG NULL
#endif
所以程序中#include "log.h"之前要定义LOG_TAG,不然就为空.
再看LOGD的定义
#ifndef LOGD
#define LOGD(...) ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__))
#endif
跟进
#ifndef LOG
#define LOG(priority, tag, ...) \
   LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__)
#endif
继续
#ifndef LOG_PRI
#define LOG_PRI(priority, tag, ...) \
   android_printLog(priority, tag, __VA_ARGS__)
#endif
再跟进
#define android_printLog(prio, tag, fmt...) \
   __android_log_print(prio, tag, fmt)
__android_log_print()是位于system/core/liblog/logd_write.c内
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_write()
int __android_log_write(int prio, const char *tag, const char *msg)
{
   ......
   return write_to_log(log_id, vec, 3);
}
write_to_log定义如下
static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) =
   __write_to_log_init;
查看一下
static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr)
{
#ifdef HAVE_PTHREADS
   pthread_mutex_lock(&log_init_lock);
#endif
   if (write_to_log == __write_to_log_init) {
       log_fds[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY);
       log_fds[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY);
       log_fds[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY);
       write_to_log = __write_to_log_kernel;
       if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0 ||
               log_fds[LOG_ID_EVENTS] < 0) {
           log_close(log_fds[LOG_ID_MAIN]);
           log_close(log_fds[LOG_ID_RADIO]);
           log_close(log_fds[LOG_ID_EVENTS]);
           log_fds[LOG_ID_MAIN] = -1;
           log_fds[LOG_ID_RADIO] = -1;
           log_fds[LOG_ID_EVENTS] = -1;
           write_to_log = __write_to_log_null;
       }
   }
#ifdef HAVE_PTHREADS
   pthread_mutex_unlock(&log_init_lock);
#endif
   return write_to_log(log_id, vec, nr);
}
这段的主要意思是打开/dev/log/main,/dev/log/radio,/dev/log/events三个设备都成功则将
write_to_log指向__write_to_log_kernel,否则指向__write_to_log_null。
下面就分别看看这两个
static int __write_to_log_null(log_id_t log_fd, struct iovec *vec, size_t nr)
{
   return -1;
}
static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr)
{
   ssize_t ret;
   int log_fd;
   if (/*(int)log_id >= 0 &&*/ (int)log_id < (int)LOG_ID_MAX) {
       log_fd = log_fds[(int)log_id];
   } else {
       return EBADF;
   }
   do {
       ret = log_writev(log_fd, vec, nr);
   } while (ret < 0 && errno == EINTR);
   return ret;
}
__write_to_log_null()什么也不做,表示丢弃log信息。__write_to_log_kernel会调用log_writev()
将log写进对应的设备(/dev/log/*).
为什么写进init.rc里由init来执行的程序不能输出log呢?下面再来探究一番。。
system/core/init/init.c中,
void service_start(struct service *svc)函数启动服务,有这么一句
       if (needs_console) {
           setsid();
           open_console();
       } else {
           zap_stdio();
       }
而这两个函数为:
static void zap_stdio(void)
{
   int fd;
   fd = open("/dev/null", O_RDWR);
   dup2(fd, 0);
   dup2(fd, 1);
   dup2(fd, 2);
   close(fd);
}
static void open_console()
{
   int fd;
   if ((fd = open(console_name, O_RDWR)) < 0) {
       fd = open("/dev/null", O_RDWR);
   }
   dup2(fd, 0);
   dup2(fd, 1);
   dup2(fd, 2);
   close(fd);
}
zap_stdio()比较狠,直接将STDIN,STDOUT,STDERR都干掉了,而open_console()则只是在/dev/console
不存在的情况下才干掉STDIN,STDOUT,STDERR,如果/dev/console存在,则将所有输入输出重定向到它

调用哪个取决于needs_console,
needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0;
而svc->flags关于SVC_CONSOLE的部分来自于system/core/init/parser.c
static void parse_line_service(struct parse_state *state, int nargs, char **args)
{
      case K_console:
       svc->flags |= SVC_CONSOLE;
       break;
}
这也就是说如果init.rc中service部分有请求console,则可以打印到console。
但怎么样才能打印到系统的log中,可以使用logcat来查看呢?这就需要用到logwrapper。
system/core/logwrapper/logwrapper.c中,logwrapper先打开/dev/ptmx,查询到设备名后
fork()一个子进程并将STDOUT,STDERR定向到查询到的设备。
       // redirect stdout and stderr
       close(parent_ptty);
       dup2(child_ptty, 1);
       dup2(child_ptty, 2);
       close(child_ptty);
然后开始执行要运行的程序
child(argc - 1, &argv[1]);

总结:
系统中的程序中输出log一般是到/dev/log/下的三个设备中,可以用logcat查看。
对于init运行的程序则有两种方法查看到log信息:
1.添加/system/bin/logwrapper,可以用logcat查看,例如
service /system/bin/logwrapper /system/bin/rild
2.添加console,像sh一样直接输出到console
service console /system/bin/sh
     console

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/guopeixin/archive/2010/06/09/5659279.aspx

[转]NDK中log输出方法相关推荐

  1. android简化log输出方法

    android简化版log输出 希望实现的效果: 只需要将类实现ILog接口(不需要进行任何额外的操作),然后就能直接通过printLog进行日志的输出 如下: class A implements ...

  2. android系统开发中log的使用方法

    1. Linux内核的log输出 使用printk打印级别且将信息保存到/proc/kmsg日志中,使用cat命令查看其信息[ cat /proc/kmsg ] 2. android中log输出 an ...

  3. swift LOG 输出

    Log 输出是程序开发中很重要的组成部分,虽然它并不是直接的业务代码,但是却可以忠实地反映我们的程序是如何工作的,以及记录程序运行的过程中发生了什么. 在 Swift 中,最简单的输出方法就是使用 p ...

  4. java log输出到文件路径_log4j中日志输出文件指定相对路径的方法

    log4j中日志输出文件指定相对路径的方法 1.设置在 C:/log/error.log log4j.appender.E = org.apache.log4j.RollingFileAppender ...

  5. Android中获取WebView加载的html中console.log输出的内容

    场景 Android中使用WebView加载本地html并支持运行JS代码和支持缩放: Android中使用WebView加载本地html并支持运行JS代码和支持缩放_BADAO_LIUMANG_QI ...

  6. android jni 中实现 LOG 输出调试

    android jni 中实现 LOG 输出调试 在jni 文件夹下 android.mk文件中 添加 LOCAL_LDLIBS += -L$(SYSTEM)/usr/lib -llog 在jni中添 ...

  7. php 像页面输出html,PHP在页面中原样输出HTML代码的方法介绍

    本篇文章给大家介绍一下PHP在页面中原样输出HTML代码的方法.有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助. 字符串与HTML之间的相互转换主要应用htmlentities()函数 ...

  8. 如何使cmd的输入和输出重定向到管道中(用这种方法可以将指令写入cmd并抓取输出)

    / //                                                                                      // //      ...

  9. python右对齐格式化输出_Python中格式化输出的两种方法介绍

    本篇文章给大家带来的内容是关于Python中格式化输出的两种方法介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 方式一:使用占位符 % 常用占位符:% s (s = string ...

最新文章

  1. 集成学习(Bagging和AdaBoost和随机森林(random forest))
  2. 2张表,轻松搞定你的收入问题
  3. springboot异步注解_Spring Boot 2 :Spring Boot 中的响应式编程和 WebFlux 入门
  4. oracle12c没有有sqlnet文件,Oracle的sqlnet.ora文件配置
  5. html界面左侧没有顶格,求解,html页面顶部有空白??
  6. iOS多任务:suspend VS terminate
  7. 抖音回应视频泄露:草稿不会上传后台;苹果开卖5000元印度版iPhone XR;Jboot 2.2.5发布|极客头条...
  8. UVALIve 5987 素数
  9. 常见花材的固定的方法有哪些_固定无梁拱形屋顶的方法都有哪些呢?
  10. podman—网络设置、开机自启及加速器配置
  11. 【macOS】Desktop桌面文件突然消失不见解决办法
  12. 快递单号查询国外公司编码汇总_快递鸟
  13. 5800交点正反算坐标(可计算不对称缓和曲线)
  14. 双硬盘安装Windows+Ubuntu
  15. 任何情况下请通过正规渠道变更信用卡额度
  16. 2019 春季算法工程师实习生招聘历程
  17. HDU-1863 畅通工程
  18. Python爬虫 requests使用post请求发送文件
  19. QT QLineEdit焦点和键盘问题
  20. 我错过了乔布斯和初代 iPhone,十年后幸好没错过你

热门文章

  1. mfc 饼图绘画_绘画技能干货 | 【人体头颈】的绘画技巧(三)(内含母亲节抽奖公布)...
  2. linux WiFi源码解析,Wifi移植浅析
  3. aliyun maven 添加jar_阿里云Maven配置,Maven仓库配置,Maven镜像配置
  4. java赋_Java赋值运算符(=)
  5. laravel打印sql语句_SQL语句为什么慢?索引为什么失效?
  6. PYG教程【四】Node2Vec节点分类及其可视化
  7. Spark Streaming(一)概述
  8. Python最佳代码实践:性能、内存和可用性!
  9. PDF下载!提高代码质量的一本书
  10. Chrome常用快捷键整理汇总