1. Android Logcat的是建立在Android的日志系统之上的,日志系统包括内核驱动模块Logger(drivers/staging/android)和liblog.so(源码位于/system/core/liblog下),liblog.so主要提供日志数据的写入与读取接口,向下负责操作底层log驱动,向上一是提供ALOG功能给Native C与java提供log写入,另一方面是提供给Logcat模块将日志系统中的日志数据读取出来并输出到当前系统的STDOUT。

2 adb logcat本质只是从日志系统中循环读取数据,所以也负责将日志数据回显到系统的标准输出中去。

当我们在java层使用一条Log.v()或者在Native层使用ALOGD()时,日志系统会将当前的message数据记录

当我们adb logcat(本质只是/bin/adbd进程服务间接帮助执行了logcat),其本质就是个可执行文件,当logcat执行时,他会默认去读取日志系统中的message数据,也是借助liblog.so来读取日志文件,当一个message被读取到时,在回显到标准输出前,他会做一个几个和换行符\n相关的加工处理:

a.向message一行输出中自动添加prefix和suffix

01-08 17:28:48.731   884  1078 I vol.EventswriteEvent active_stream_changed UNKNOWN_STREAM_-1
01-08 17:28:48.733   884  1523 D OpenGLRendererdrawRenderNode

这里的prefix如上01-08 17:28:48.733   884  1523 D 为值,从代码中体现如下:

logcat.cpp:main->processBuffer->android_log_printLogLine->android_log_formatLogLine:

    strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm);
        case FORMAT_THREADTIME:prefixLen = snprintf(prefixBuf, sizeof(prefixBuf),"%s.%03ld %5d %5d %c %-8s: ", timeBuf, entry->tv_nsec / 1000000,entry->pid, entry->tid, priChar, entry->tag);        strcpy(suffixBuf, "\n");suffixLen = 1;break;

这里可以明显看到prefix产生的原因,分别是日志写入时的时间格式还有进程和线程号;

对suffix处理时默认是加入一个\n符,这也就解释了为何一行日志message包裹\n还能具备换行输出的原因(STDOUT标准输出在printf时每遇到一个\n就会自动换行,具体由内核驱动实现,用户只需加入\n符号即可)。

b:判断message的字符串中是否包含/n,如果是的话,认为/n后续的字符是需要另起一行并添加对应的Prefix和suffix,即要当中两条message来处理:

        while(pm < (entry->message + entry->messageLen)) {const char *lineStart;size_t lineLen;lineStart = pm;// Find the next end-of-line in messagewhile (pm < (entry->message + entry->messageLen)&& *pm != '\n') pm++;lineLen = pm - lineStart;strcat(p, prefixBuf);p += prefixLen;strncat(p, lineStart, lineLen);p += lineLen;strcat(p, suffixBuf);p += suffixLen;if (*pm == '\n') pm++;}}

上述代码是将message中的buf单个读取后,遇到\n前的所有字符会被添加prefix和suffix,即message中的一个\n是输出一行带有prefix和suffix的数据缓存字段:。

列入ALOGD("hello\n\nworld\n\n");

01-08 17:28:48.733   884  1523 D TAG      : hello

01-08 17:28:48.733   884  1523 D TAG      :

01-08 17:28:48.733   884  1523 D TAG      :  world

01-08 17:28:48.733   884  1523 D TAG      :

01-08 17:28:48.733   884  1523 D TAG      : xxx

出现的前4行行数据意味着有4个\n的存在

默认行尾不存在\n时会自动加入\n符号,末尾只存在一个\n时只会解析为一行输出并加入\n,ALOGD中写入的\n只作为一个数据的标志符。

总结,每个\n用来表示接下去将会换行开始输出ALOG中的字符日志数据(当新的一行没有日志数据时,只会显示prefix相关的内容),当一行日志输出到末尾时,无论末尾有无\n都会进行一次自动换行,目的是表示当前ALOD结束接下去要开始启动输出下一个全新的ALOG中所定义的日志数据。

Android Logcat输出为何能自动换行输出的原因以及多\n的作用相关推荐

  1. Eclipse Android LogCat有时候显示不出输出的原因

    在开发Android的过程当中,不知道怎么搞的有时候Logcat就是不显示打印的信息,觉得不爽于是终于发现解决方法如下: 点DDMS 然后选择对应的模拟器就可以了

  2. 使用 ADB LogCat 查看在Android真机上 Unity debug.log 输出日志

    控制台窗口输入指令格式为:[adb] logcat [<option>] ... [<filter-spec>] ... 其中的 [<option>] 的指令都有: ...

  3. Eclipse设置Android Logcat输出字体大小

    Window -> Preferences -> Android -> Logcat -> Display Font:点击"Change"按钮 如图: 

  4. android执行命令行取得结果,Android调用shell脚本并取得输出

    Android调用shell脚本并获得输出 前段时间做的HLS流媒体服务器可以正常工作了,但是它的启动需要在PC机命令行中进行或者在Android下载个Terminal IDE软件,在Android上 ...

  5. android多音频输出,基于Android车载系统的多路音频输出的方法、装置及系统与流程...

    本发明涉及Android车载系统领域,特别涉及一种基于Android车载系统的多路音频输出的方法.装置及系统. 背景技术: 车载系统主要由主机.显示屏.操作键盘(遥控器)和天线组成.它实现了野外踏勘. ...

  6. 修改Android开机声音从耳机通道输出

    文档说明 本文档以SC826(MSM8953平台,Android 7)为例,说明如何修改开机声音从耳机通道输出. 不想看分析过程的,直接看 patch文件 章节. 应用背景 默认代码,在不插入耳机时, ...

  7. java自动换行输出_Java PrintStream.println打印自动换行

    首页 > 基础教程 > IO流 > OutputStream类 Java PrintStream.println打印自动换行 定义 public void println() pub ...

  8. Android Logcat的使用

    Android Logcat使用起来可以方便的观察调试内容,基本上的使用方法(巧用Logcat调试程序).本次要说明的是平时的Log.v Log.d Log.i Log.w Log.e的区别是什么? ...

  9. Android logcat log丢失

    Android logcat log丢失 一.log丢失对应方法 1.禁用黑白名单机制 2.利用黑白名单机制 3.只输出4个以内的log TAG 4.通过log等级限制数量 5.增大LogBuffer ...

  10. android logcat 命令详解

    转载自:http://www.cnblogs.com/flyingcode/p/5280501.html Android日志系统提供了记录和查看系统调试信息的功能.日志都是从各种软件和一些系统的缓冲区 ...

最新文章

  1. R语言ggplot2可视化移除数据中的NA值再可视化实战:消除图形中非常突出的NA柱状图、使用subset函数、使用drop_na函数
  2. udp_socket聊天器demo
  3. oracle数据库结束进程后怎么重启,Oracle数据库的启动与关闭方法
  4. opencv6.1-imgproc图像处理模块之平滑与形态学操作
  5. oracle数据库的高可用r,Oracle高可用之dataguard
  6. Android自定义控件系列
  7. 简单java socket_基于Java Socket实现一个简易在线聊天功能(一)
  8. golang 使用 redis 的教程
  9. SQL Server CONVERT() 函数,Date 函数
  10. 《MySQL——Innodb改进LRU算法》
  11. Windows10 virtualbox安装alpine+docker
  12. 不重启docker容器修改 容器中的时区
  13. asp.net抓取网页html源代码失败 只因UserAgent作怪
  14. 世界超级计算机比赛,【启明之星】何斌:刷新超级计算机比赛世界纪录
  15. 电子电路仿真软件中文版_一个电子工程师的自我修养
  16. 计算机视觉知识点-车型识别
  17. 迷你KMS mini-KMS_Activator_v1.3_Office2010_VL_ENG使用
  18. 障碍期权定价 python_Python二项期权定价
  19. centos7编写shell批处理文件和执行方法
  20. 非洲越来越多年轻人希望用加密货币支付

热门文章

  1. 通信笑笑点(2010.08.14)
  2. Win10安装Centos8 Stream
  3. linux嵌入式主要学什么软件,嵌入式软件工程师需要学什么?嵌入式Linux开发的工作内容...
  4. 分数阶 计算机应用,基于分数阶Riemann-Liouville积分的图像去噪
  5. Verifying archive integrity... Error in check sums 1981929512 2439459451
  6. 微软Kinect for windows SDK 使用教程一 (NUI部分)
  7. GitHub 上这份计算机自学指南火了~
  8. 计算机专业移民,计算机专业成为新晋移民专业了!
  9. CF1016C Vasya And The Mushrooms
  10. 干货丨如何优雅地设计并控制一台协作机械臂