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 message            while (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中所定义的日志数据。





更多相关文章

  1. android 图形系统加速学习系列 (一)
  2. SQLite的使用
  3. Android获取和设置系统环境变量指南
  4. android Uri使用
  5. Android应用架构之MVVM模式
  6. Android系统启动流程分析
  7. Android(安卓)多个APK共享数据(Shared User ID)
  8. Android短信拦截机制适配的坑(下)--4.4以上系统,主要是6.0
  9. Android学习-SharedPreferences接口的学习

随机推荐

  1. android in practice_Communicating chan
  2. 模拟抽奖的九宫格动画效果
  3. Android学习之使用HttpURLConnection下载
  4. Tips for Designers: from a Developer[S
  5. 垂直滚动跑马灯AutoScrollTextView
  6. Android(安卓)Calendar的运用
  7. 12.8 SeekBar和RatingBar
  8. android竖排TextView(字是横向的)
  9. Android(安卓)RecyclerView实现在线选座
  10. ERROR: Unsupported method: AndroidProj