Android 开发中 C++ 和Java 日志调试

在 C++ 中添加堆栈日志

先在 Android.bp 中 添加 ‘libutilscallstack’

 shared_libs:["liblog","	libutilscallstack"]

在想要打印堆栈的代码中添加

#include <utils/CallStack.h>
using android::CallStack;// 在函数中添加
int VisualizerLib_Create{CallStack stack(TAG);stack.update(); 
}

最后日志示例:
image.png

通过 堆栈日志,可以分析函数的调用路径。在代码跳转中了解整个调用逻辑。

系统库的源码位置

代码路径:android\system\core\libutils\include\utils\CallStack.h

// Collect/print the call stack (function, file, line) traces for a single thread.
class CallStack {
public:// Create an empty call stack. No-op.CallStack();// Create a callstack with the current thread's stack trace.// Immediately dump it to logcat using the given logtag.CallStack(const char* logtag, int32_t ignoreDepth = 1);~CallStack();// Reset the stack frames (same as creating an empty call stack).void clear() { mFrameLines.clear(); }// Immediately collect the stack traces for the specified thread.// The default is to dump the stack of the current call.void update(int32_t ignoreDepth = 1, pid_t tid = BACKTRACE_CURRENT_THREAD);// Dump a stack trace to the log using the supplied logtag.void log(const char* logtag,android_LogPriority priority = ANDROID_LOG_DEBUG,const char* prefix = nullptr) const;// Dump a stack trace to the specified file descriptor.void dump(int fd, int indent = 0, const char* prefix = nullptr) const;// Return a string (possibly very long) containing the complete stack trace.String8 toString(const char* prefix = nullptr) const;// Dump a serialized representation of the stack trace to the specified printer.void print(Printer& printer) const;// Get the count of stack frames that are in this call stack.size_t size() const { return mFrameLines.size(); }

在 C++ 中打开日志开关

#define LOG_NDEBUG 0

这里针对的是 所有 ALOGV 的日志开关,调试时需要打开上面的 define

如果只是针对联调日志,只想添加部分日志, 则加上 ALOGD 或 ALOGW 的日志

在 java 中添加日志

import android.util.Log;//
Exception e = new Exception("This is a log");
e.printStackTrace();//
Thread.currentThread().getStackTrace();//
Log.e(TAG , Log.getStackTraceString(new Throwable()));

打印日志示例:

06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): java.lang.Throwable
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.server.telecom.CallAudioRouteStateMachine.setSpeakerphoneOn(CallAudioRouteStateMachine.java:1655)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.server.telecom.CallAudioRouteStateMachine.reinitialize(CallAudioRouteStateMachine.java:1898)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.server.telecom.CallAudioRouteStateMachine.access 2200 ( C a l l A u d i o R o u t e S t a t e M a c h i n e . j a v a : 73 ) 06 − 0416 : 19 : 29.648 D / C a l l A u d i o R o u t e S t a t e M a c h i n e ( 1070 ) : a t c o m . a n d r o i d . s e r v e r . t e l e c o m . C a l l A u d i o R o u t e S t a t e M a c h i n e 2200(CallAudioRouteStateMachine.java:73) 06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.server.telecom.CallAudioRouteStateMachine 2200(CallAudioRouteStateMachine.java:73)060416:19:29.648D/CallAudioRouteStateMachine(1070):atcom.android.server.telecom.CallAudioRouteStateMachineActiveSpeakerRoute.processMessage(CallAudioRouteStateMachine.java:1223)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.internal.util.StateMachine S m H a n d l e r . p r o c e s s M s g ( S t a t e M a c h i n e . j a v a : 993 ) 06 − 0416 : 19 : 29.648 D / C a l l A u d i o R o u t e S t a t e M a c h i n e ( 1070 ) : a t c o m . a n d r o i d . i n t e r n a l . u t i l . S t a t e M a c h i n e SmHandler.processMsg(StateMachine.java:993) 06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at com.android.internal.util.StateMachine SmHandler.processMsg(StateMachine.java:993)060416:19:29.648D/CallAudioRouteStateMachine(1070):atcom.android.internal.util.StateMachineSmHandler.handleMessage(StateMachine.java:810)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at android.os.Handler.dispatchMessage(Handler.java:106)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at android.os.Looper.loopOnce(Looper.java:201)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at android.os.Looper.loop(Looper.java:288)
06-04 16:19:29.648 D/CallAudioRouteStateMachine( 1070): at android.os.HandlerThread.run(HandlerThread.java:67)

附件: C++的宏定义打印格式

# 打印 bool 类型
bool doProcess = !mEffectCallback->isOffloadOrMmap() && !mEffectCallback->isOffloadOrDirect();ALOGD("doProcess: %s", doProcess ? "true" : "false"); //true:0 False:1ALOGW%s mEffects[%zu] name %s", __func__, i, mEffects[i]->desc().name);
//W/AudioFlinger::EffectChain(  862): process_l  mEffects[0] name Visualizer// 测试某个函数的方法打印
ALOGD("----------%s---------",__func__);%d输出int型。
%zu输出size_t型。size_t在库中定义为unsigned int。
一个是整型,一个是无符号整型(无法打印负数)。
补充:如果%zu不能使用,可以用%u取代。%zu,%u不能输出负数。%@     对象
%d, %i 整数
%u     无符整形
%f     浮点/双字
%x, %X  16进制整数
%x     --- 一般的16进制的打印
%2x   --- 要求打印2个16进制位,不够2个位的时候使用空格填充
%02x --- 要打印2个16进制位,不够2个位的时候使用0填充
%o     八进制整数
%zu    size_t
%p     指针
%e     浮点/双字 (科学计算)
%g     浮点/双字
%s     C 字符串
%.*s   Pascal字符串
%c     字符
%C     unichar
%lld   64位长整数(long long)
%llu   无符64位长整数
%Lf    64位双字

其他 格式的,请参考:

C语言中printf打印形式(%02X, %2X, %-2X, %.nf, %m.nf, %e, %m.ne, %2d, %-2d, %02d, %.2d)_printf %.2x-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/43264.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

生物素结合金纳米粒子(Bt@Au-NPs ) biotin-conjugated Au-NPs

一、定义与特点 定义&#xff1a;生物素结合金纳米粒子&#xff0c;简称BtAu-NPs或biotin-conjugated Au-NPs&#xff0c;是指通过特定的化学反应或物理方法将生物素修饰到金纳米粒子表面&#xff0c;形成稳定的纳米复合材料。 特点&#xff1a; 高稳定性&#xff1a;生物素的修…

【VUE基础】VUE3第七节—Vue Router路由基础

Vue Router 是 Vue 官方的客户端路由解决方案。 客户端路由的作用是在单页应用 (SPA) 中将浏览器的 URL 和用户看到的内容绑定起来。当用户在应用中浏览不同页面时&#xff0c;URL 会随之更新&#xff0c;但页面不需要从服务器重新加载。 Vue Router 基于 Vue 的组件系统构建&…

LabVIEW在半导体自动化测试中的应用

半导体制造的复杂性和精密度要求极高&#xff0c;每一个生产步骤都需要严格的控制和监测。自动化测试设备在半导体制造中起到了关键作用&#xff0c;通过精密测量和数据分析&#xff0c;确保产品质量和生产效率。本文介绍如何使用LabVIEW结合研华硬件&#xff0c;开发一个用于半…

C语言编程3:运算符,运算符的基本用法

C语言3&#x1f525;&#xff1a;运算符&#xff0c;运算符的基本用法 一、运算符&#x1f33f; &#x1f387;1.1 定义 运算符是指进行运算的动作&#xff0c;比如加法运算符"“&#xff0c;减法运算符”-" 算子是指参与运算的值&#xff0c;这个值可能是常数&a…

自动化测试高级控件交互方法:TouchAction、触屏操作、点按,双击,滑动,手势解锁!

在自动化测试领域中&#xff0c;TouchAction 是一种非常强大的工具&#xff0c;它允许我们模拟用户在设备屏幕上的各种触摸事件。这种模拟不仅限于简单的点击操作&#xff0c;还包括滑动、长按、多点触控等复杂的手势。 点按与双击 点按和双击是触屏设备上最基本的操作之一。…

使用 Qt 和 ECharts 进行数据可视化

文章目录 示例图表预览折线图散点图柱状图使用 Qt 和 ECharts 进行数据可视化一、准备工作1. 安装 Qt2. 准备 ECharts二、在 Qt 中使用 ECharts1. 创建 Qt 项目2. 配置项目文件3. 在 UI 中添加 WebEngineView4. 加载 ECharts三、创建折线图、散点图和柱状图1. 折线图2. 散点图3…

sizeof跟strlen的用法及差异

sizeof是一个操作符&#xff0c;不是函数&#xff1b; 而strlen是一个库函数&#xff1b; sizeof是计算所占内存空间的&#xff0c;不管你内容是什么&#xff0c;只要知道占多少内存&#xff0c; 而strlen是跟内容有关的&#xff0c;它是计算字符串长度的&#xff08;字符数…

java —— tomcat 部署项目

一、通过 war 包部署 1、将项目导出为 war 包&#xff1b; 2、将 war 包放置在 tomcat 目录下的 webapps 文件夹下&#xff0c;该 war 包稍时便自动解析为项目文件夹&#xff1b; 3、启动 tomcat 的 /bin 目录下的 startup.bat 文件&#xff0c;此时即可从浏览器访问项目首页…

【Linux】文件内容查看命令——cat,tac,more,less,head,tail,od

如果我们要查看一个文件的内容时&#xff0c;该如何是好&#xff1f; 这里有相当多有趣的命令可以来分享一下&#xff1a;最常使用的显示文件内容的命令可以说是cat与more及less了。 此外&#xff0c;如果我们要查看一个很大的文件&#xff08;好几百MB时)&#xff0c;但是我们…

使用PyTorch设计卷积神经网络(CNN)来处理遥感图像Indian Pines数据集

目录 使用PyTorch设计卷积神经网络&#xff08;CNN&#xff09;来处理遥感图像Indian Pines数据集&#xff0c;以下是设计和实现这些网络的步骤&#xff1a; 1.数据准备&#xff1a; 1.1 首先&#xff0c;需要加载Indian Pines数据集。 1.2 将数据集转换为PyTorch张量&#x…

LLM推理引擎怎么选?TensorRT vs vLLM vs LMDeploy vs MLC-LLM

LLM擅长文本生成应用程序&#xff0c;如聊天和代码完成模型&#xff0c;能够高度理解和流畅。但是它们的大尺寸也给推理带来了挑战。有很多个框架和包可以优化LLM推理和服务&#xff0c;所以在本文中我将整理一些常用的推理引擎并进行比较。 TensorRT-LLM TensorRT-LLM是NV发布…

imazing电脑怎么下载 imazing怎么下载软件 使用iMazing下载和卸载Apple设备上的应用程序

iMazing官方版是一款管理苹果设备的软件&#xff0c;是一款帮助用户管理 iOS手机的PC端应用程序&#xff0c;能力远超 iTunes 提供的终极 iOS 设备管理器。在iMazing官方版上与苹果设备连接后&#xff0c;可以轻松传输文件&#xff0c;浏览保存信息等&#xff0c;功能比iTunes更…

泛微开发修炼之旅--35关于基于页面扩展和自定义按钮实现与后端交互调用的方法

文章链接&#xff1a;35关于基于页面扩展和自定义按钮实现与后端交互调用的方法

vue3中使用 tilwindcss报错 Unknown at rule @tailwindcss

解决方法&#xff1a; vscode中安装插件 Tailwind CSS IntelliSense 在项目中的 .vscode中 settings.json添加 "files.associations": {"*.css": "tailwindcss"}

基于YOLOv9的脑肿瘤区域检测

数据集 脑肿瘤区域检测&#xff0c;我们直接采用kaggle公开数据集&#xff0c;Br35H 数据中已对医学图像中脑肿瘤位置进行标注 数据集我已经按照YOLO格式配置好&#xff0c;数据内容如下 数据集中共包含700张图像&#xff0c;其中训练集500张&#xff0c;验证集200张 模型训…

AI绘画:艺术与科技的交融,创新浪潮与无限可能

在科技日新月异的当下&#xff0c;AI 绘画作为人工智能领域的一颗璀璨新星&#xff0c;正以惊人的速度在国内崭露头角&#xff0c;引发了艺术与技术交融的全新变革。随着人工智能技术的飞速发展&#xff0c;AI绘画已成为艺术与科技交融的新宠。2024年&#xff0c;AI绘画行业在国…

Autogen智能体实战-Autogen框架介绍

文章目录 一&#xff0c;Autogen简介二&#xff0c;Autogen原理1&#xff0c;Autogen原理图解2&#xff0c;拆解Autogen是如何完成绘制特斯拉股票趋势图的 这篇文章介绍一个开源的Agent框架-微软的Autogen。 一&#xff0c;Autogen简介 官网:https://microsoft.github.io/aut…

在idea中查看某个接口的所有实现类图

一、选中某个接口右键 ---> Diagrams ---> show Diagrams&#xff0c;然后就会进入一个新的 tab 页&#xff1b; 二、然后在出来的图上选中某个接口右键 ---> show Implementations&#xff0c;就会显示选中接口的所有实现类列表&#xff1b; 三、最后 ctrl A 全部选…

uniapp父页面调用子页面 组件方法记录

文章目录 导文如何点击父页面&#xff0c;触发子页面函数先写一个子页面的基础内容父元素 如何点击父页面&#xff0c;修改子页面的值先写一个子页面的基础内容父元素 导文 如何点击父页面&#xff0c;触发子页面函数&#xff1f; 如何点击父页面&#xff0c;修改子页面的值&am…

英区PayPal账号3分钟绑定WISE英镑的银行收款账户

正文开始&#xff0c;我们先登录英区PayPal账号后 有很多银行给我们选择&#xff0c;但是没有WISE的选项&#xff0c;所以我们手动输入“WISE”&#xff0c;然后如下图所示点击“Enter Your Bank Detailds”输入银行详细信息按钮。 然后输入我们的WISE英镑账户的收款银行信息&a…