写点什么

小技巧 _ 在 Android Studio 调试应用,android 开发实战项目

作者:嘟嘟侠客
  • 2021 年 11 月 28 日
  • 本文字数:3742 字

    阅读完需:约 12 分钟


您会发现断点的图标发生了改变:



现在,您的应用只会在前一个断点被触发后才会在此断点停止运行。


这个功能也可以用在其他使用了条件断点的地方,从而可以避免复制粘贴条件断点到新位置的操作。

挂起线程

如果您在调试一个多线程应用,您将会注意到,在默认情况下断点将会挂起所有线程,但有时您可能不希望它这样做。举例来说,您可能想要验证某个后台线程阻塞时,应用的其他功能是否能够正常工作,或者您希望了解在执行一个后台任务时,UI 能不能够持续进行渲染。


为了仅挂起当前线程,您需要打开断点选项,并且选中? Suspend ?设置中的? Thread ?选项:


Evaluate and log?(评估与记录)

有些时候,相比起在断点处停止运行,您可能更希望看到一些有关应用状态的信息。也许您会通过在代码中添加 println 语句来做到这一点,但这种方法需要重新编译应用,您其实可以利用断点本身来进行评估与记录。


为了做到这点,您需要在断点选项中禁用? Suspend ?并启用? Evaluate and log :



现在,您可以在输入框中添加任何代码表达式,相应内容会被评估并记录至控制台。


如果您只是想快速验证断点是否触发并且不在乎其中的细节信息,可以使用? "Breakpoint hit"?信息 来记录断点的触发事件。您甚至可以使用 Shift + 添加断点的方式来让这一操作变得更加快捷。

禁用断点


禁用断点 (并非删除断点),可以右键点击断点并从弹框中取消选中 Enabled 选框。您也可以通过按住 Alt (在 Mac 上是 Option) 并点击断点,从而更快速地禁用断点。

断点分组

您一定遇到过这种场景: 您正在解决一个 Bug,并为此添加了几个断点,但是发现自己一时间没什么头绪,所以您就去解决别的 Bug 了。然而,很快您就开始触发为了解决第一个 Bug 所添加的断点。触发无关的断点不但会让人困扰,还会把您带离您的调试流程。


您可以使用断点分组来让开发过程更舒心一些。


当您的程序运行到第一个与当前调试流程无关的断点时,右击并打开? More ?菜单,这时您会看到一个所有断点的列表,您可以在这里复选所有与第一个 Bug 相关的断点:



右击选中的断点,并选择? Move to group ?接下来?? Create new ?并为新的分组命名,例如以您正在处理的 Bug 命名。现在,您可以仅通过点击轻松地启用和禁用所有的断点了。



当然,您也可以在解决了 Bug 之后,使用分组功能删除所有相关的断点。

Drop frame (丢弃当前帧)

有些时候,当您浏览挂起的代码时,可能会意外跳过某个本应该进入的方法。如果您的设备运行的是 Android 10 或者更高版本,您可以通过点击调试工具栏中的? Drop Frame ?按钮来进行回溯:



这个功能会把您从当前的方法带回到其开始执行前的节点,从而给您一个重新进入该方法的机会。


此功能并不是?"时间机器"。如果您正处于一个长函数的中间位置,而它此前已经执行了许多工作 (例如,修改了当前类的状态)。在您丢弃当前帧时,这类操作所产生的改变不会被撤销。

Mark object (标记对象)

有时候,您会想要跟踪某些特定类型实例的生命周期。本例中,要跟踪的对象有一个哈希值: @10140:



为了能够在这个对象再次出现时可以认出它来,您可能已经掏出纸笔准备记下这个数字了。不过您也可以选择另一种方式: 右击该对象,点击? Mark Object ?为其添加标签。


这样一来,无论被标记的对象出现在调试窗口的任何地方,它都会带有您添加的标签以方便辨认。这里我们为该对象添加一个 " myItem "?标签:



更棒的是,就算您处于完全不同的上下文,无法触及到刚才的对象,您也可以在? Watches ?窗口对其进行查看。无论您处在什么位置,只要触发断点,就可以在? Watches ?窗口添加后缀为 " _DebugLabel "?的标签 (不用担心自己会不记得后缀的内容,这里有自动补全):



现在,您可以在任何地方使用? Watches ?窗口来观察该类型对象的状态。


您也可以将此功能与条件断点组合。举例来说,您可打一个断点,右击并为其设置一个条件来检查打了标签的对象:



这样一来,就不用在进入包含特定实例的范围之前跳过一堆断点,代码会运行到合适的地方再停止:


Evaluate expression (评估表达式)

尽管? Variables ?和? Watches ?窗口对于跟踪某个显式值时已经十分好用,但您有时候还是会想要更加自由地探索您的代码,这时候就轮到评估表达式功能登场了。当您正处于某个断点时,您可以使用调试工具栏中的? Evaluate expression ?按钮来访问这一功能。



您可以在 Expression 输入框中输入任何表达式,点击?Evaluate?按钮就可以对其进行评估。当然,如果您评估了一个对象,在评估完成后,您就可以在 Result?部分浏览该对象的详细信息:



评估表达式弹窗可能会以单行模式打开,您可以通过点击? Expand ?来将其扩展为多行模式:



现在,您可以输入复杂的多行表达式,其中可以包含变量、i


《Android 学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》

【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享


f 语句等各种内容:


Apply changes

前面讲过,当您使用条件断点时,会需要评估一个表达式;即便代码没有在断点停止,调试器依然需要执行评估操作。如果您在一个非常紧密的循环中运行评估操作,例如游戏中的动画处理,则可能导致应用停顿。尽管条件断点很有用,但在某些情况下您可能无法依靠它们。


解决此问题的一种方法是将条件表达式添加到代码中,并使用无操作 (no-op) 表达式,从而使其可以附加断点:



在修改完代码之后,您可能会决定重启应用并点击? Debug ?按钮,但是如果您的应用运行在 Android 8 或更高版本的系统中,您可以使用? Apply Code Changes



现在,嵌入的表达式已经修补了您的代码,但您仍然会在? Frames ?窗口中看到您已经更新的方法被标记为 过时 (Obsolete) :



这是因为,虽然新的代码已经打好了补丁,但是调试器指向的仍是旧的代码。您可以使用丢弃当前帧的功能来离开旧的方法,然后进入修改过的方法之中。


尽管本例中并不需要,但这里还有一种选择:? Apply Changes and Restart Activity 。不同于? Apply Code Changes ,该操作会重启 Activity。如果您修改了布局资源或您要调试的代码,例如在 onCreate 方法中,该选项将非常有用。


分析堆栈信息

就算您掌握了所有的窍门与技巧,您的代码仍然可能出现 Bug,而您也会因此收到一些崩溃报告,这些报告中则可能包含了异常堆栈信息的文本副本。您可以使用 Analyze?菜单中的?Analyze Stack Trace or Thread Dump 将这些信息转化为有意义的内容。


此工具提供了一个粘贴堆栈信息的文本框,不过它也会自动填充系统剪贴板中的文本:



点击? OK ?之后,就会将包含完整注释的堆栈信息添加到控制台:



您可以一眼看出来自您自己代码文件的内容 (以蓝色突出显示) 与您可能不需要关注的代码 (以灰色突出显示)。并且,您可以通过单击链接在您的代码文件中进行跳转。

结语

本文提供了一些可以加快调试速度的技巧和窍门。由于篇幅所限,更多技巧简单归纳如下:


《设计思想解读开源框架》


第一章、 热修复设计


  • 第一节、 AOT/JIT & dexopt 与 dex2oat

  • 第二节、 热修复设计之 CLASS_ISPREVERIFIED 问题

  • 第三节、热修复设计之热修复原理

  • 第四节、Tinker 的集成与使用(自动补丁包生成)


  • 第二章、 插件化框架设计

  • 第一节、 Class 文件与 Dex 文件的结构解读

  • 第二节、 Android 资源加载机制详解

  • 第三节、 四大组件调用原理

  • 第四节、 so 文件加载机制

  • 第五节、 Android 系统服务实现原理


  • 第三章、 组件化框架设计

  • 第一节、阿里巴巴开源路由框——ARouter 原理分析

  • 第二节、APT 编译时期自动生成代码 &动态类加载

  • 第三节、 Java SPI 机制

  • 第四节、 AOP&IOC

  • 第五节、 手写组件化架构


  • 第四章、图片加载框架

  • 第一节、图片加载框架选型

  • 第二节、Glide 原理分析

  • 第三节、手写图片加载框架实战


  • 第五章、网络访问框架设计

  • 第一节、网络通信必备基础

  • 第二节、OkHttp 源码解读

  • 第三节、Retrofit 源码解析


  • 第六章、 RXJava 响应式编程框架设计

  • 第一节、链式调用

  • 第二节、 扩展的观察者模式

  • 第三节、事件变换设计

  • 第四节、Scheduler 线程控制


  • 第七章、 IOC 架构设计

  • 第一节、 依赖注入与控制反转

  • 第二节、ButterKnife 原理上篇、中篇、下篇

  • 第三节、Dagger 架构设计核心解密


  • 第八章、 Android 架构组件 Jetpack

  • 第一节、 LiveData 原理

  • 第二节、 Navigation 如何解决 tabLayout 问题

  • 第三节、 ViewModel 如何感知 View 生命周期及内核原理

  • 第四节、 Room 架构方式方法

  • 第五节、 dataBinding 为什么能够支持 MVVM

  • 第六节、 WorkManager 内核揭秘

  • 第七节、 Lifecycles 生命周期

  • 本文包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…


本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

用户头像

嘟嘟侠客

关注

还未添加个人签名 2021.03.19 加入

还未添加个人简介

评论

发布
暂无评论
小技巧 _ 在 Android Studio 调试应用,android开发实战项目