IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Android源码分析-logcat源码分析,以及mainradiosystem等log文件,包括select的多路复用的运用 -> 正文阅读

[游戏开发]Android源码分析-logcat源码分析,以及mainradiosystem等log文件,包括select的多路复用的运用

logcat简介:

logcat用于输出日志到屏幕上,也可以将日志重定向到文件中。本篇主要分析logcat源码,顺便说一下logcat的典型用法。

logcat本身是一个可执行程序,需要依赖于adb命令执行,或者说,需要在adb shell命令行运行。
例如:

adb logcat > 1.log //将日志输出到1.log文件中。

adb shell

logcat -b main. // 输出类型为main的日志

-b <buffer> ,指定要查看的日志缓冲区,是一个可选项。可以是system,events,radio,main。默认值是system和main 。可选值为:

system, events?, radio, main

可以用-help来列出logcat的使用方法:

logcat -help

结果如下:?

?其余常用的选项是:

-c 清楚屏幕上的日志.? ?

例如,logcat -c

logcat源码分析:

编译:
logat源码主要分布在:?

system/core/logcat/logcat.cpp
system/core/include/cutils/logger.h

看Android.mk文件:

可见,使用了liblog库,编译出来的结果是可执行程序logcat。

我们从logcat.cpp的main函数开始分析。

核心代码如下:

int main(int argc, char **argv)
{
    ......

//1. 参数check和解析
    g_logformat = android_log_format_new();

    if (argc == 2 && 0 == strcmp(argv[1], "--test")) {
        logprint_run_tests();
        exit(0);
    }

    if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
        android::show_help(argv[0]);
        exit(0);
    }

   // 参数的继续处理
    for (;;) {
        int ret;
        ret = getopt(argc, argv, "cdt:gsQf:r::n:v:b:B");

        if (ret < 0) {
            break;
        }

        switch(ret) {
            case 's': 
                // default to all silent
                android_log_addFilterRule(g_logformat, "*:s");
            break;

            case 'c':
                clearLog = 1;
                mode = O_WRONLY;
            break;
        ......
    }

//2. devices的过滤
if (!devices) {
        devices = new log_device_t(strdup("/dev/"LOGGER_LOG_MAIN), false, 'm');
        android::g_devCount = 1;
        int accessmode =
                  (mode & O_RDONLY) ? R_OK : 0
                | (mode & O_WRONLY) ? W_OK : 0;
        // only add this if it's available
        if (0 == access("/dev/"LOGGER_LOG_SYSTEM, accessmode)) {
            devices->next = new log_device_t(strdup("/dev/"LOGGER_LOG_SYSTEM), false, 's');
            android::g_devCount++;
        }
    }

//dev = devices;
    while (dev) {
        dev->fd = open(dev->device, mode);

......

//3.读取一行
android::readLogLines(devices);
}

分析:

1)根据输入的参数,进行相应的分析和处理:

例如,输入--help,就调用

android::show_help(argv[0]);

//显示help信息。

然后进入for无限循环。在for循环中,进一步进行参数处理。包括getopt中的这些值。

?ret = getopt(argc, argv, "cdt:gsQf:r::n:v:b:B");

函数用于过滤参数中是否包含cdt:gsQf:r::n:v:b:B中的值,并且返回这个值。

对于res的处理:

这个for循环也相对容易理解。有兴趣的同学可以继续看源代码。

2)对devices的分析:

devices的类型定义在logger.h中,如下:

#define LOGGER_LOG_MAIN		"log/main"
#define LOGGER_LOG_RADIO	"log/radio"
#define LOGGER_LOG_EVENTS	"log/events"
#define LOGGER_LOG_SYSTEM	"log/system"

可见,logcat -b后面的参数对应于文件系统中的某一个(几个)文件。

3)readLines函数的实现:

实现原理,实现一个无限循环,采用select多路复用,从

devices

中获取数据,这里的devices就是前面提到的

system, events?, radio, main

,核心代码片段如下:

?多路复用select: 监听devices设备,超时时间设置为5ms。将结果通过read函数读取到内存中,即读取到queued_entry_t相关的内存中。

queued_entry_t数据结构的定义:
struct log_device_t {
    char* device;
    bool binary;
    int fd;
    bool printed;
    char label;

    queued_entry_t* queue;
    log_device_t* next;

    log_device_t(char* d, bool b, char l) {
        device = d;
        binary = b;
        label = l;
        queue = NULL;
        next = NULL;
        printed = false;
    }

    void enqueue(queued_entry_t* entry) {
        if (this->queue == NULL) {
            this->queue = entry;
        } else {
            queued_entry_t** e = &this->queue;
            while (*e && cmp(entry, *e) >= 0) {
                e = &((*e)->next);
            }
            entry->next = *e;
            *e = entry;
        }
    }
};

这是一个队列,用链表实现的。

附:多路复用select的使用:

Linux系统中IO多路复用select函数的使用,及其在Android系统中的运用_liranke的博客-CSDN博客


  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-04-01 00:25:36  更:2022-04-01 00:27:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:06:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码