0
点赞
收藏
分享

微信扫一扫

Android系统10 RK3399 init进程启动(十六) Android Log日志编写

配套系列教学视频链接:

      ​​安卓系列教程之ROM系统开发-百问100ask​​

说明

系统:Android10.0

设备: FireFly RK3399 (ROC-RK3399-PC-PLUS)

前言

Android系统中日志基本都是通过log系统来实现, 在代码中可以通过相应的接口来输出不同等级的日志, 不同的缓冲区有不同的API, 等级有Verbose, Debug,Info,Warn,Error。本章节主要讲解log日志的API。

一, 日志系统框架

之前的的课程中讲解了整体框架, 此处贴图让大家提升印象:

Android系统10 RK3399 init进程启动(十六) Android Log日志编写_android

系统也提供的Java和C++/C语言不同的API:

  1. 在java层调用import android.util.Log,在需要打印Log的地方执行Log.v,Log.d,Log.i,Log.w,Log.e.
  2. c、c++层调用:在c,c++层包含此头文件:

老版本包含 #include <cutils/log.h>,代码调用LOGV,LOGD,LOGI,LOGW,LOGE

新版本包含 #include <log/log.h>, 代码调用ALOGV,ALOGD,ALOGI,ALOGW,ALOGE。

二, Android 不同缓冲区的API

Android系统中包含不同缓冲区, 特定缓冲区用的API不同:

main:查看主日志缓冲区(默认),不包含系统和崩溃日志消息。

system:查看系统日志缓冲区(默认)。

radio:查看包含无线装置/电话相关消息的缓冲区。

events:查看已经过解译的二进制系统事件缓冲区消息。

crash:查看崩溃日志缓冲区(默认)。

all:查看所有缓冲区。

default:报告 main、system 和 crash 缓冲区。

Main缓冲区API(JAVA/C/C++):

C/C++:

        ALOGV(), ALOGD(),ALOGI(),ALOGW(),ALOGE()

Log.java

        Log.v(),Log.d(),Log.i(),Log.w(),Log.e(),

Radio缓冲区API(JAVA/C/C++):

C/C++

        RLOGV(), RLOGD(),RLOGI(),RLOGW(),RLOGE()

        当然还有一种条件日志:  ALOGD_IF(),RLOGD_IF(),

RLog.java: 普通app是无法使用该接口的

        RLog.v(),RLog.d(),RLog.i(),RLog.w(),RLog.e(),

System缓冲区API(JAVA): 普通app是无法使用该接口的

import android.util.Slog; //​​frameworks​​​/​​base​​​/​​core​​​/​​java​​​/​​android​​​/​​util​​​/​​Slog.java​​​​Slog​​.​​d​​(​​TAG​​, “xxxx”); 

Events缓冲区API(JAVA):

import android.util.EventLog;

int ​​writeEvent​​​(int ​​tag​​​, ​​Object​​​... ​​list​​);

使用:​​EventLog​​​.​​writeEvent​​​(​​WM_TASK_REMOVED​​​, ​​mTaskId​​, "removeTask");

Crash缓冲区:主要是由system/core/debuggered守护进程打印(如输出tombstone文件的内容)

01-12 03:52:39.196 22371 22371 F DEBUG    #78 pc 0028f6ef  /

​​system​​​/​​core​​​/​​debuggerd​​​/​​libdebuggerd​​​/​​utility.cpp​​

_LOG()==> ​​__android_log_buf_write​​​(​​LOG_ID_CRASH​​​, ​​ANDROID_LOG_FATAL​​​, ​​LOG_TAG​​​, ​​msg​​​.​​c_str​​());

三,所有API的底层实现

虽然缓冲区不同,API不同,其实内部实现都会有一些通用参数, 如:

java层buferID    ​​Log​​​.​​LOG_ID_SYSTEM​​

C/C++层buferID:  LOG_ID_RADIO

C/C++层Log级别: ANDROID_LOG_DEBUG

C/C++所有接口实现在liblog中, 可以在Android.mk或者Android.bp中加入liblog, 并引入头文件和宏定义:

#define LOG_TAG "xxxx"

#include <log/log.h>

而system/core/include/log/log.h 有如下包含, 说明不同缓冲区的接口都被包含到了log.h中:

Android系统10 RK3399 init进程启动(十六) Android Log日志编写_Android底层_02

各个缓冲区的写日志的API其实最终是调用:

int ​​__android_log_print​​​(int ​​prio​​​, const char* ​​tag​​​, const char* ​​fmt​​, ...)

        |//​​system​​​/​​core​​​/​​liblog​​​/​​logger_write.cpp​​ 

        int ​​__android_log_buf_write​​​(int ​​bufID​​​, int ​​prio​​​, const char* ​​tag​​​, const char* ​​msg​​) 

         这个函数就没有可变参数

在NDK编写jni时, 你会常看见如下定义, 其实就是最终调用了上面的统一接口:

#define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG,__VA_ARGS__) // 定义LOGD类型

#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG,__VA_ARGS__) // 定义LOGI类型

#define LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG,__VA_ARGS__) // 定义LOGW类型

#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG,__VA_ARGS__) // 定义LOGE类型

四:总结

  不同语言使用不通的API, 其实都不是太复杂, 最终都是写入到不同缓冲区中。


举报

相关推荐

0 条评论