Logcat源码分析(四)

来源:互联网 发布:a星算法 定位 编辑:程序博客网 时间:2024/06/02 14:17
继续看logcat.cppreadLogLines()这个函数
if (result == 0) {  
    // we did our short timeout trick and there's nothing new   
    // print everything we have and wait for more data   
    sleep = true;  
    while (true) {  
        chooseFirst(devices, &dev);  
        if (dev == NULL) {  
            break;  
        }  
        if (g_tail_lines == 0 || queued_lines <= g_tail_lines) {  
            printNextEntry(dev);  
        } else {  
            skipNextEntry(dev);  
        }  
        --queued_lines;  
    }  
  
    // the caller requested to just dump the log and exit   
    if (g_nonblock) {  
        exit(0);  
    }  
} else {  
    // print all that aren't the last in their list   
    sleep = false;  
    while (g_tail_lines == 0 || queued_lines > g_tail_lines) {  
        chooseFirst(devices, &dev);  
        if (dev == NULL || dev->queue->next == NULL) {  
            break;  
        }  
        if (g_tail_lines == 0) {  
            printNextEntry(dev);  
        } else {  
            skipNextEntry(dev);  
        }  
        --queued_lines;  
    }  
}  
        如果result == 0,表明是等待超时了,目前没有新的日志可读,这时候就要先处理之前已经读出来的日志。调用chooseFirst选择日志队列不为空,且日志队列中的第一个日志记录的时间戳为最小的设备,即先输出最旧的日志:
static void chooseFirst(log_device_t* dev, log_device_t** firstdev) {  
    for (*firstdev = NULL; dev != NULL; dev = dev->next) {  
        if (dev->queue != NULL && (*firstdev == NULL || cmp(dev->queue, (*firstdev)->queue) < 0)) {  
            *firstdev = dev;  
        }  
    }  
}  
       如果存在这样的日志设备,接着判断日志记录是应该丢弃还是输出。前面我们说过,如果执行logcat命令时,指定了参数-t <count>,那么就会只显示最新的count条记录,其它的旧记录将被丢弃:
if (g_tail_lines == 0 || queued_lines <= g_tail_lines) {  
     printNextEntry(dev);  
else {  
     skipNextEntry(dev);  
}  
         g_tail_lines表示显示最新记录的条数,如果为0,就表示全部显示如果g_tail_lines == 0或者queued_lines <= g_tail_lines,就表示这条日志记录应该输出,否则就要丢弃了每处理完一条日志记录,queued_lines就减1,这样,最新的g_tail_lines条日志就可以输出出来了。
如果result > 0表明有新的日志可读,这时候的处理方式与result == 0的情况不同,因为这时候还有新的日志可读,所以就不能先急着处理之前已经读出来的日志。这里,分两种情况考虑,如果设置了只显示最新的g_tail_lines条记录,并且当前已经读出来的日志记录条数已经超过g_tail_lines,就要丢弃,剩下的先不处理,等到下次再来处理,即暂时没新日志产生时才处理,也就是说只能在result == 0中被输出;如果没有设备显示最新的g_tail_lines条记录,即g_tail_lines == 0,这种情况就和result  == 0的情况处理方式一样,先处理所有已经读出的日志记录,再进入下一次循环。希望读者可以好好体会这段代码
while (g_tail_lines == 0 || queued_lines > g_tail_lines) {  
     chooseFirst(devices, &dev);  
     if (dev == NULL || dev->queue->next == NULL) {  
          break;  
     }  
     if (g_tail_lines == 0) {  
          printNextEntry(dev);  
     } else {  
          skipNextEntry(dev);  
     }  
     --queued_lines;  
}  
丢弃日志记录的函数skipNextEntry实现如下:
static void skipNextEntry(log_device_t* dev) {  
    maybePrintStart(dev);  
    queued_entry_t* entry = dev->queue;  
    dev->queue = entry->next;  
    delete entry;  
}  
这里只是简单地跳过日志队列头,这样就把最旧的日志丢弃了。
printNextEntry函数处理日志输出,下一节中继续分析。