# 逮虾户!Android程序调试竟简单如斯

逮虾户!Android程序调试竟简单如斯

PS:行吧,不用百度了,逮虾户是《头文字D》的一首配乐《Deja vu》,中文谐音 “逮虾户”,飙车漂移专用BGM,有时音乐响起也暗示着:开车。

[图片上传中...(image-d9031b-1545903959476-61)]

当然本节讨论的不是开车,而是Android开发中老生常谈的程序调试。

[图片上传中...(image-c12305-1545903959476-60)]

一个开发仔的日常离不开:写BUG和解BUG,特别是多人协作的时候, 帮别人擦屁股(解Bug)的情况屡见不鲜。另外,接盘别人的项目,着手解 Bug也能帮你快速的上手项目。综上,修炼好「调试」这门技能显得尤为重要。 但是,但是感觉很多玩家还停留下无脑打印的阶段,所以有了这篇文章。

[图片上传中...(image-963d33-1545903959476-59)]

笔者尽量以最精简的方式来过一过Android调试中的(qi)(ji)(yin)(qiao)。

[图片上传中...(image-24d2c-1545903959475-58)]

逮虾户~


1.无脑静态调试

解释下这个标题:

  • 无脑觉得哪里有问题就打印哪里
  • 静态:每次想打印,都要去修改代码,然后重新运行程序。

适用于:想查看变量的值在某一时刻是否异常!

接着来说下两种常用的调试方法:

Toast打印法

新手Android开发仔最爱调试法,使用简便,仅需一行代码,轻松打印:

Toast.makeText(MainActivity.this, "Toast调试", Toast.LENGTH_SHORT).show();
复制代码

方便是挺方便的,不过有一点要注意:Android 5.0后,如果把「消息通知的权限」 关闭掉的话,部分机型是不会显示Toast的!你还可以使用Snackbar来显示值进行调试:

Snackbar.make(父view, "Snackbar调试", Snackbar.LENGTH_SHORT).show();
复制代码

或者其他变通的方法,比如在页面上添加一个TextView,把值直接显示在文本框上。

Log日志打印法

Toast调试是挺爽的,但是有两个问题:

  • 1.想调试打印多个值的话,Toast会弹个不停,毕竟同一时刻只有「一个」Toast显示在前台;
  • 2.Toast间隔一段时间后会消失,即使你设置了Toast.LENGTH_LONG

可能你一走神,没来得及看调试的值,Toast就消失了。我们着实需要一种无需担心调试 结果消失的方法——「Log日志打印法」,就是利用Android系统提供的Log类,在调试 的地方,把日志打印到「Logcat控制台」上,使用方法也非常简单:

Log.d("TAG", "Log调试")
复制代码

当代码执行到这一句的时候,就会在Logcat控制台打印调试信息,另外Logcat默认 会打印出所有的日志信息,我们可以做一些过滤来定位到我们调试的日志信息。 首先是:「日志类型」,Android支持6种日志类型,依次如下:

  • Verbose:详细,所有类型的日志信息。
  • Debug:调试,调试用的日志信息。
  • Info:信息,正常使用时需要关注的日志信息。
  • Warn:警告,可能有问题,但没发生错误的日志信息。
  • Error:错误,运行时出现严重错误的日志信息。
  • Assert:断言。

温馨提示

不要上来就Error级别,我以前打Log全部用Log.e,原因是日志信息是红色的,好看... 结果被组长屌了一顿,o(TωT)o ,觉得颜色不好看,你可以按照下述的操作进行自定义。

打开「Settings」-> 「Editor」->「Colors Scheme」->「Android Logcat」 选择日志类型,然后去掉勾选,然后点击选择颜色色值

[图片上传中...(image-215dbc-1545903959473-22)]

这是笔者配色方案,读者可以自行调整为喜欢的颜色:

  • Assert:8F0005
  • Debug:0070BB
  • Error:FF0006
  • Info:48BB31
  • Verbose:BBBBBB
  • Warning:BBBB23

设置后的配色如图所示:

[图片上传中...(image-cfedfe-1545903959473-21)]

行吧,知道可以通过Log类打印调试和自定义Logcat配色,顺带也提提「日志过滤」的姿势吧。

  • 自定义Logcat日志头信息的显示内容:点击面板上的「Logcat Header」来设置日志头信息

[图片上传中...(image-a21e68-1545903959475-57)]

可选设置内容如下:

[图片上传中...(image-f0e2d7-1545903959475-56)]

右侧还可以「过滤日志信息」,支持正则,再右面是过滤特定日志的选项。

[图片上传中...(image-882-1545903959475-55)]

如果觉得还不够的话,可以点击最右侧的「Edit Filter Configuration」来配置一个自己的过滤器。

[图片上传中...(image-12a221-1545903959475-54)]

另外,还可以对进行「日志搜索」,鼠标点击Logcat中间区域获得焦点,Ctrl + F 调出 搜索工具栏,接着搜索相关的日志内容。

[图片上传中...(image-ea1c16-1545903959475-53)]

顺带提下Log类的一个容易忽略的小坑:

Log类只会打印4000个字符,超过部分不打印!!!

2.有脑动态调试法

其实就是用Android Studio提供的Debug模式来程序调试,相比起前面的 Toast打印法和Log日志打印法,稍微复杂一点,要点学习成本,还有动脑子, 最重要是可以动态调试,很多新手玩家貌似对这个都望而却步,其实不难,待我 带你九浅一深,em...由浅入深走一遭,来学学Android Studio Debug核心技巧。

[图片上传中...(image-c92ce4-1545903959475-52)]

1)基本的调试流程

一般的调试流程图如下所示:(核心就是下断点,单步调试,值跟踪

[图片上传中...(image-736885-1545903959475-51)]

2)下断点

先说说断点,不是张敬轩的《断点》,调试时的断点的作用是:

当程序执行到断点所在的代码时,会暂停应用程序的运行,线程被挂起,然后 可以通过调试器进行跟踪。

下断点的方式也很简单,点击某行代码的左侧,会出现如图所示的小红点。

[图片上传中...(image-6563a2-1545903959475-50)]

这个小红点就是断点,而在AS中,又有着多种类型的断点,带你们过一遍吧:

  • 行断点

就是上面这种,对特定行进行调试时用到,点击行所在的左侧边栏即可设置。 右键点击这个断点,会弹出如下所示的设置对话框:

[图片上传中...(image-c38ad-1545903959475-49)]

如果你取消了Enabled勾选,断点就处于如图所示的禁用状态:

[图片上传中...(image-381e35-1545903959475-48)]

  • 方法断点

如果你把断点下到一个方法前,断点就会变成这样:

[图片上传中...(image-18fd2b-1545903959475-47)]

这个就是方法断点,一般用来检查方法的「输入参数」与「返回值」。

[图片上传中...(image-7526b-1545903959475-46)]

  • 变量断点

有时我们对程序运行过程并不关心,而只关注某个变量的变化,可以在变量定义前加一个断点。

[图片上传中...(image-f421-1545903959475-45)]

在程序运行过程中,如果该变量的值发生改变,程序会自动停下来,并定位到变量值改变的地方,供开发者调试。

[图片上传中...(image-4b1e7c-1545903959475-44)]

另外,右键还可以设置断点,Watch面板有两个特有的选项,可按需勾选:

  • Field access:字段被访问时触发断点。
  • Field modification:字段被修改时触发断点。
  • 条件断点(断点设置Condition)

有时会有这样的场景:把断点打到循环体的中,我们只关心特定循环次数下的运行情况。 比如一个循环10次的循环体,我们想知道循环到第8次时的运行情况,如果你不知道 条件断点的话,你需要一直按「Run to Cursor」直到满足我们的条件。比如下面的代码:

[图片上传中...(image-f8eac1-1545903959475-43)]

我们想知道当i = 8的时候,sum为多少,你需要一直按「Run to Cursor」

[图片上传中...(image-a7f32d-1545903959475-42)]

按7次,直到i = 9位置,如果用条件断点,当循环体执行到某个条件才停下来,右键断点,输入如图所示的等式条件:

[图片上传中...(image-dd8552-1545903959474-41)]

然后可以发现,程序直接跳到i=8的时候才挂起,非常方便。

[图片上传中...(image-6ac3b-1545903959474-40)]

  • 日志断点

调试的时候我们可以通过打印日志的方式来定位异常代码大概位置,以缩小引发问题的范围,然后 再使用断点精确定位问题。如果是普通的打印日志,我们需要等待重新构建程序,如果用「日志断点」 就避免这个无意义的等待。使用日志断点非常简单,右键断点,去掉「Suspend」的勾选,会出现 如下所示的弹窗,勾选「Evaluate and log」在此输入想输出的内容。

[图片上传中...(image-fe7234-1545903959474-39)]

运行调试后,当执行到日志断点的时候可以看到控制台输出了对应的日志信息,而且程序正常运行,并不会挂起。

[图片上传中...(image-32b8b2-1545903959474-38)]

如果想查看更详细的信息,比如断点的位置和触发时的堆栈信息,可以勾选「"Breakpint hit" message」和「Stacktrace」,勾选后输出内容会变得更详细:

[图片上传中...(image-2938b7-1545903959474-37)]

  • 临时断点

所谓的临时断点就是:触发一次后就自动删除的断点。设置的方法有两种:

  • 1.光标移到想打点的行,点击菜单栏「Run」->「Toggle Temporary Line Breakpoint」, 等价于快捷键:「Ctrl+Alt+Shift+F8
  • 2.更便捷的操作:按住Alt,鼠标点击左侧边栏。

[图片上传中...(image-45d8e3-1545903959474-36)]

鼠标点击后可以去掉临时断点,如果想把临时断点变成普通断点,可以取消勾选 「Remove once hit」的选项。

[图片上传中...(image-808682-1545903959474-35)]

  • 异常断点

用于监听程序异常,一旦程序奔溃,直接定位到异常所在的确切位置。依次点击: 「Run」->「View Breakpoints」打开断点视图。点击「+」,然后选择 「Java Exception Breakpoints」,在弹出的窗口中输入要调试的异常:

[图片上传中...(image-57628c-1545903959474-34)]

[图片上传中...(image-abf0c9-1545903959474-33)]

除了设置异常断点外,你在这里看到项目设置的所有断点,并进行断点管理与配置。 另外,你还可以设置自定义异常断点,点击「4.Exception Breakpoints」自行配置即可。


3)进入调试模式的另一种方式

大部分的同学调试都是通过点击下面这个只小虫子进入调试模式。

[图片上传中...(image-7e1802-1545903959474-32)]

这种方法有个缺点就是:每次都需要重新运行程序,可能有这样的场景:把APP丢给测试 测试,然后出现了一个很稀有的BUG,此时你如果用普通的Debug模式,需要重启APP,但是 Bug不一定能够复现,这就很尴尬了。对于需要动态调试的场景,可以「直接调试正在运行的 Android进程」,点击如下所示的另一个有小虫子的图标:

[图片上传中...(image-11c89c-1545903959474-31)]

然后选择要调试的包名,就可以无需重启应用直接进行调试了:

[图片上传中...(image-8657b1-1545903959474-30)]


4)调试工具详解

这里把调试工具划分为如图所示的五个区域一个个讲解:

[图片上传中...(image-854f18-1545903959474-29)]

  • A区步进调试工具
图标 名称 功能描述
[图片上传中...(image-44f8cc-1545903959470-15)]

| 显示执行点 | 定位到当前正在调试的断点。 |
| [图片上传中...(image-ae7f4-1545903959470-14)]

| 单步跳过 | 一步一步执行,遇到方法直接执行完方法,进入下一步,不会进入方法内部。 |
| [图片上传中...(image-b4d9bf-1545903959470-13)]

| 单步进入 | 一步一步执行,遇到方法且是自定义的方法,则进入方法内部,否则不会进入。 |
| [图片上传中...(image-e2ba7b-1545903959470-12)]

| 强制进入 | 遇到方法无论是自定义的还是官方类库的,都会进入方法内部。 |
| [图片上传中...(image-106c4a-1545903959470-11)]

| 单步跳出 | 跳出当前进入的方法,返回方法调用处的下一行(也意味着方法被执行完毕)。 |
| [图片上传中...(image-20fe41-1545903959470-10)]

| 丢弃帧 | 如果你在某个方法内,执行完丢弃帧,当前方法会被中断,返回方法被调用的
地方,变量的值也会重置。 |
| [图片上传中...(image-4882e9-1545903959470-9)]

| 执行到光标处 | 可以看做是临时断点,程序运行到当前光标所在行暂停。 |
| [图片上传中...(image-1638c3-1545903959470-8)]

| 计算表达式 | 支持在调试过程中,通过赋值或表达式方式修改任意变量的值。 |

!!!注意:上面的执行到光标处是有个前提的:中途没有断点,如果你想强制执行到 光标处的话,你需要「Force Run to Cursor」,你可以通过下述两种方式进行操作:

  • 1.光标处右键,选中「Force Run to Cursor」,如图:

[图片上传中...(image-e59d54-1545903959472-20)]

  • 2.使用快捷键:Ctrl + Alt + F9。

计算表达式(Evaluate Expression)

非常实用,可以动态地查看和修改任意变量得值,除了上面在调试窗口点击计算器图标可以打开外, 你可以在D区点击某个变量右键打开。演示下修改某个变量得值:

[图片上传中...(image-e3883a-1545903959472-19)]

修改完后,点击Evaluate,结果如下:

[图片上传中...(image-93fc8a-1545903959472-18)]

你也可以在这里直接查看变量的值,示例如下:

[图片上传中...(image-7399ba-1545903959472-17)]

同样点击Evaluate,结果如下:[图片上传中...(image-a8a23-1545903959472-16)]

  • B区控制调试工具
图标 名称 功能描述
[图片上传中...(image-a73547-1545903959470-7)]

| 继续程序运行 | 程序运行到某个断点暂停,如果有下一个断点,点击后跳到这个断点,
没有的话,程序则继续运行。 |
| [图片上传中...(image-4767be-1545903959470-6)]

| 暂停程序运行 | 暂停程序运行。 |
| [图片上传中...(image-d163ea-1545903959470-5)]

| 终止程序运行 | 终止程序运行。 |
| [图片上传中...(image-170329-1545903959470-4)]

| 查看断点 | 可以查看所有的断点,管理与断点配置 |
| [图片上传中...(image-6c9a30-1545903959470-3)]

| 禁用所有断点 | 切换所有断点的状态(启用/禁用),禁用后,程序就不会触发断点。 |
| [图片上传中...(image-63980f-1545903959470-2)]

| 获得线程堆栈 | 显示线程的相关信息 |
| [图片上传中...(image-74f31c-1545903959470-1)]

| 恢复布局 | 恢复到原始布局 |
| [图片上传中...(image-156b38-1545903959470-0)]

| 设置 | 调试的相关配置,比如是否显示执行方法后的返回值 |

  • C区帧调试窗口

这里的帧指的是:堆栈帧,一种用于「存储数据」和「部分过程结果」的数据结构; 每次调用方法在堆栈中都会占用一部分内存,单位是,随着方法调用而创建。 每个堆栈帧中包括了:「传入参数」、「返回地址」、「局部变量」以及「对程序调试提供支持的信息」。一个线程包括多个堆栈帧。

[图片上传中...(image-2b8733-1545903959473-28)]

查看工具那里可以以上下顺序切换的方方式查看帧(鼠标直接点击也可以),最右侧的漏斗图标 点击后可以过滤掉:「非本应用的帧」。另外,你还可以右键堆栈帧,添加「步进过滤器」、 「导出线程」或「自定义线程显示」。

  • D区变量区

在这个区域可以看到堆栈帧中当前所有的数据(方法参数、本地变量、实例变量)。 右键某个变量,可以进行「设置\复制变量值」,「跳转到变量在代码中的位置」等操作。 一个常用的操作:选择「Add to Watches」,单独监视这个变量的变化。

  • E区监视窗口

除了前面这种右键添加监视的方法外,你还可以直接在E区点击「+」进行添加。

[图片上传中...(image-44df70-1545903959473-27)]

不止监控变量,还支持监控表达式,比如上面的i+1。 关于Android Debug调试的基本操作大概就这些,多去实战中历练巩固吧!


3.Android Wifi 无线调试

其实还是要先电脑这个也非常简单,安装一个「ADB WIFI」的插件,安装后重启:

[图片上传中...(image-fe78f4-1545903959473-26)]

然后把APP的调试模式为「Usb Device

[图片上传中...(image-456213-1545903959473-25)]

手机连接电脑,依次点击AS的菜单栏:「Tools」->「ADB USB TO WIFI 」,然后左下角会出现:

[图片上传中...(image-20c85f-1545903959473-24)]

一般来说,要扫描好久,建议自己看下手机ip,然后通过adb命令进行链接,示例如下:

adb connect 10.1.7.200:5555

# 出现下述信息代表连接成功:
connected to 10.1.7.200:5555
复制代码

连接成功后就可以拔掉数据线,进行无线调试了。


4.利用Network Profiler抓包

Android Profiler是AS 3.0后引入的性能分析工具,而Network Profiler是其中一个用于网络分析的工具, 利用它我们直接抓包,而不需借助第三方的抓包工具(比如Charles)进行分析调试。 比较简单,界面如下:

[图片上传中...(image-b65b56-1545903959473-23)]

利用它可以进行很方便的抓包操作。


关于Android程序调试的东西肯定不止这些,上述的算是基本功吧。 有更多调试技巧欢迎在评论区留言~谢谢

逮虾户!Android程序调试竟简单如斯

PS:行吧,不用百度了,逮虾户是《头文字D》的一首配乐《Deja vu》,中文谐音 “逮虾户”,飙车漂移专用BGM,有时音乐响起也暗示着:开车。

[图片上传中...(image-9f427e-1545903960445-61)]

当然本节讨论的不是开车,而是Android开发中老生常谈的程序调试。

[图片上传中...(image-b2622e-1545903960445-60)]

一个开发仔的日常离不开:写BUG和解BUG,特别是多人协作的时候, 帮别人擦屁股(解Bug)的情况屡见不鲜。另外,接盘别人的项目,着手解 Bug也能帮你快速的上手项目。综上,修炼好「调试」这门技能显得尤为重要。 但是,但是感觉很多玩家还停留下无脑打印的阶段,所以有了这篇文章。

[图片上传中...(image-7c3d10-1545903960445-59)]

笔者尽量以最精简的方式来过一过Android调试中的(qi)(ji)(yin)(qiao)。

[图片上传中...(image-9320e2-1545903960445-58)]

逮虾户~


1.无脑静态调试

解释下这个标题:

  • 无脑觉得哪里有问题就打印哪里
  • 静态:每次想打印,都要去修改代码,然后重新运行程序。

适用于:想查看变量的值在某一时刻是否异常!

接着来说下两种常用的调试方法:

Toast打印法

新手Android开发仔最爱调试法,使用简便,仅需一行代码,轻松打印:

Toast.makeText(MainActivity.this, "Toast调试", Toast.LENGTH_SHORT).show();
复制代码

方便是挺方便的,不过有一点要注意:Android 5.0后,如果把「消息通知的权限」 关闭掉的话,部分机型是不会显示Toast的!你还可以使用Snackbar来显示值进行调试:

Snackbar.make(父view, "Snackbar调试", Snackbar.LENGTH_SHORT).show();
复制代码

或者其他变通的方法,比如在页面上添加一个TextView,把值直接显示在文本框上。

Log日志打印法

Toast调试是挺爽的,但是有两个问题:

  • 1.想调试打印多个值的话,Toast会弹个不停,毕竟同一时刻只有「一个」Toast显示在前台;
  • 2.Toast间隔一段时间后会消失,即使你设置了Toast.LENGTH_LONG

可能你一走神,没来得及看调试的值,Toast就消失了。我们着实需要一种无需担心调试 结果消失的方法——「Log日志打印法」,就是利用Android系统提供的Log类,在调试 的地方,把日志打印到「Logcat控制台」上,使用方法也非常简单:

Log.d("TAG", "Log调试")
复制代码

当代码执行到这一句的时候,就会在Logcat控制台打印调试信息,另外Logcat默认 会打印出所有的日志信息,我们可以做一些过滤来定位到我们调试的日志信息。 首先是:「日志类型」,Android支持6种日志类型,依次如下:

  • Verbose:详细,所有类型的日志信息。
  • Debug:调试,调试用的日志信息。
  • Info:信息,正常使用时需要关注的日志信息。
  • Warn:警告,可能有问题,但没发生错误的日志信息。
  • Error:错误,运行时出现严重错误的日志信息。
  • Assert:断言。

温馨提示

不要上来就Error级别,我以前打Log全部用Log.e,原因是日志信息是红色的,好看... 结果被组长屌了一顿,o(TωT)o ,觉得颜色不好看,你可以按照下述的操作进行自定义。

打开「Settings」-> 「Editor」->「Colors Scheme」->「Android Logcat」 选择日志类型,然后去掉勾选,然后点击选择颜色色值

[图片上传中...(image-31ab9d-1545903960444-22)]

这是笔者配色方案,读者可以自行调整为喜欢的颜色:

  • Assert:8F0005
  • Debug:0070BB
  • Error:FF0006
  • Info:48BB31
  • Verbose:BBBBBB
  • Warning:BBBB23

设置后的配色如图所示:

[图片上传中...(image-1d37af-1545903960443-21)]

行吧,知道可以通过Log类打印调试和自定义Logcat配色,顺带也提提「日志过滤」的姿势吧。

  • 自定义Logcat日志头信息的显示内容:点击面板上的「Logcat Header」来设置日志头信息

[图片上传中...(image-c86b44-1545903960445-57)]

可选设置内容如下:

[图片上传中...(image-9053e5-1545903960445-56)]

右侧还可以「过滤日志信息」,支持正则,再右面是过滤特定日志的选项。

[图片上传中...(image-625930-1545903960445-55)]

如果觉得还不够的话,可以点击最右侧的「Edit Filter Configuration」来配置一个自己的过滤器。

[图片上传中...(image-cf21d8-1545903960445-54)]

另外,还可以对进行「日志搜索」,鼠标点击Logcat中间区域获得焦点,Ctrl + F 调出 搜索工具栏,接着搜索相关的日志内容。

[图片上传中...(image-40633d-1545903960445-53)]

顺带提下Log类的一个容易忽略的小坑:

Log类只会打印4000个字符,超过部分不打印!!!

2.有脑动态调试法

其实就是用Android Studio提供的Debug模式来程序调试,相比起前面的 Toast打印法和Log日志打印法,稍微复杂一点,要点学习成本,还有动脑子, 最重要是可以动态调试,很多新手玩家貌似对这个都望而却步,其实不难,待我 带你九浅一深,em...由浅入深走一遭,来学学Android Studio Debug核心技巧。

[图片上传中...(image-37cbaa-1545903960445-52)]

1)基本的调试流程

一般的调试流程图如下所示:(核心就是下断点,单步调试,值跟踪

[图片上传中...(image-547be1-1545903960445-51)]

2)下断点

先说说断点,不是张敬轩的《断点》,调试时的断点的作用是:

当程序执行到断点所在的代码时,会暂停应用程序的运行,线程被挂起,然后 可以通过调试器进行跟踪。

下断点的方式也很简单,点击某行代码的左侧,会出现如图所示的小红点。

[图片上传中...(image-d7eb88-1545903960445-50)]

这个小红点就是断点,而在AS中,又有着多种类型的断点,带你们过一遍吧:

  • 行断点

就是上面这种,对特定行进行调试时用到,点击行所在的左侧边栏即可设置。 右键点击这个断点,会弹出如下所示的设置对话框:

[图片上传中...(image-9b92af-1545903960445-49)]

如果你取消了Enabled勾选,断点就处于如图所示的禁用状态:

[图片上传中...(image-3c0a5-1545903960445-48)]

  • 方法断点

如果你把断点下到一个方法前,断点就会变成这样:

[图片上传中...(image-ca7265-1545903960445-47)]

这个就是方法断点,一般用来检查方法的「输入参数」与「返回值」。

[图片上传中...(image-5cffe1-1545903960445-46)]

  • 变量断点

有时我们对程序运行过程并不关心,而只关注某个变量的变化,可以在变量定义前加一个断点。

[图片上传中...(image-d86b53-1545903960445-45)]

在程序运行过程中,如果该变量的值发生改变,程序会自动停下来,并定位到变量值改变的地方,供开发者调试。

[图片上传中...(image-598347-1545903960445-44)]

另外,右键还可以设置断点,Watch面板有两个特有的选项,可按需勾选:

  • Field access:字段被访问时触发断点。
  • Field modification:字段被修改时触发断点。
  • 条件断点(断点设置Condition)

有时会有这样的场景:把断点打到循环体的中,我们只关心特定循环次数下的运行情况。 比如一个循环10次的循环体,我们想知道循环到第8次时的运行情况,如果你不知道 条件断点的话,你需要一直按「Run to Cursor」直到满足我们的条件。比如下面的代码:

[图片上传中...(image-8c2a4e-1545903960445-43)]

我们想知道当i = 8的时候,sum为多少,你需要一直按「Run to Cursor」

[图片上传中...(image-481b54-1545903960445-42)]

按7次,直到i = 9位置,如果用条件断点,当循环体执行到某个条件才停下来,右键断点,输入如图所示的等式条件:

[图片上传中...(image-627fe1-1545903960445-41)]

然后可以发现,程序直接跳到i=8的时候才挂起,非常方便。

[图片上传中...(image-7b5639-1545903960445-40)]

  • 日志断点

调试的时候我们可以通过打印日志的方式来定位异常代码大概位置,以缩小引发问题的范围,然后 再使用断点精确定位问题。如果是普通的打印日志,我们需要等待重新构建程序,如果用「日志断点」 就避免这个无意义的等待。使用日志断点非常简单,右键断点,去掉「Suspend」的勾选,会出现 如下所示的弹窗,勾选「Evaluate and log」在此输入想输出的内容。

[图片上传中...(image-a18314-1545903960445-39)]

运行调试后,当执行到日志断点的时候可以看到控制台输出了对应的日志信息,而且程序正常运行,并不会挂起。

[图片上传中...(image-f89856-1545903960445-38)]

如果想查看更详细的信息,比如断点的位置和触发时的堆栈信息,可以勾选「"Breakpint hit" message」和「Stacktrace」,勾选后输出内容会变得更详细:

[图片上传中...(image-13abc9-1545903960444-37)]

  • 临时断点

所谓的临时断点就是:触发一次后就自动删除的断点。设置的方法有两种:

  • 1.光标移到想打点的行,点击菜单栏「Run」->「Toggle Temporary Line Breakpoint」, 等价于快捷键:「Ctrl+Alt+Shift+F8
  • 2.更便捷的操作:按住Alt,鼠标点击左侧边栏。

[图片上传中...(image-8ddf07-1545903960444-36)]

鼠标点击后可以去掉临时断点,如果想把临时断点变成普通断点,可以取消勾选 「Remove once hit」的选项。

[图片上传中...(image-a03185-1545903960444-35)]

  • 异常断点

用于监听程序异常,一旦程序奔溃,直接定位到异常所在的确切位置。依次点击: 「Run」->「View Breakpoints」打开断点视图。点击「+」,然后选择 「Java Exception Breakpoints」,在弹出的窗口中输入要调试的异常:

[图片上传中...(image-e1ee1a-1545903960444-34)]

[图片上传中...(image-68f8d5-1545903960444-33)]

除了设置异常断点外,你在这里看到项目设置的所有断点,并进行断点管理与配置。 另外,你还可以设置自定义异常断点,点击「4.Exception Breakpoints」自行配置即可。


3)进入调试模式的另一种方式

大部分的同学调试都是通过点击下面这个只小虫子进入调试模式。

[图片上传中...(image-6bb53b-1545903960444-32)]

这种方法有个缺点就是:每次都需要重新运行程序,可能有这样的场景:把APP丢给测试 测试,然后出现了一个很稀有的BUG,此时你如果用普通的Debug模式,需要重启APP,但是 Bug不一定能够复现,这就很尴尬了。对于需要动态调试的场景,可以「直接调试正在运行的 Android进程」,点击如下所示的另一个有小虫子的图标:

[图片上传中...(image-a356e-1545903960444-31)]

然后选择要调试的包名,就可以无需重启应用直接进行调试了:

[图片上传中...(image-c3447b-1545903960444-30)]


4)调试工具详解

这里把调试工具划分为如图所示的五个区域一个个讲解:

[图片上传中...(image-56d3b3-1545903960444-29)]

  • A区步进调试工具
图标 名称 功能描述
[图片上传中...(image-46eec9-1545903960442-15)]

| 显示执行点 | 定位到当前正在调试的断点。 |
| [图片上传中...(image-fef36b-1545903960442-14)]

| 单步跳过 | 一步一步执行,遇到方法直接执行完方法,进入下一步,不会进入方法内部。 |
| [图片上传中...(image-f4f84c-1545903960442-13)]

| 单步进入 | 一步一步执行,遇到方法且是自定义的方法,则进入方法内部,否则不会进入。 |
| [图片上传中...(image-e641d-1545903960442-12)]

| 强制进入 | 遇到方法无论是自定义的还是官方类库的,都会进入方法内部。 |
| [图片上传中...(image-2114ca-1545903960442-11)]

| 单步跳出 | 跳出当前进入的方法,返回方法调用处的下一行(也意味着方法被执行完毕)。 |
| [图片上传中...(image-4e1de6-1545903960442-10)]

| 丢弃帧 | 如果你在某个方法内,执行完丢弃帧,当前方法会被中断,返回方法被调用的
地方,变量的值也会重置。 |
| [图片上传中...(image-d5a616-1545903960442-9)]

| 执行到光标处 | 可以看做是临时断点,程序运行到当前光标所在行暂停。 |
| [图片上传中...(image-eca014-1545903960442-8)]

| 计算表达式 | 支持在调试过程中,通过赋值或表达式方式修改任意变量的值。 |

!!!注意:上面的执行到光标处是有个前提的:中途没有断点,如果你想强制执行到 光标处的话,你需要「Force Run to Cursor」,你可以通过下述两种方式进行操作:

  • 1.光标处右键,选中「Force Run to Cursor」,如图:

[图片上传中...(image-9cf0fe-1545903960443-20)]

  • 2.使用快捷键:Ctrl + Alt + F9。

计算表达式(Evaluate Expression)

非常实用,可以动态地查看和修改任意变量得值,除了上面在调试窗口点击计算器图标可以打开外, 你可以在D区点击某个变量右键打开。演示下修改某个变量得值:

[图片上传中...(image-57a3d1-1545903960443-19)]

修改完后,点击Evaluate,结果如下:

[图片上传中...(image-8410aa-1545903960443-18)]

你也可以在这里直接查看变量的值,示例如下:

[图片上传中...(image-7ef0c0-1545903960443-17)]

同样点击Evaluate,结果如下:[图片上传中...(image-a2f05b-1545903960443-16)]

  • B区控制调试工具
图标 名称 功能描述
[图片上传中...(image-53a0b3-1545903960442-7)]

| 继续程序运行 | 程序运行到某个断点暂停,如果有下一个断点,点击后跳到这个断点,
没有的话,程序则继续运行。 |
| [图片上传中...(image-df08e6-1545903960442-6)]

| 暂停程序运行 | 暂停程序运行。 |
| [图片上传中...(image-10404b-1545903960442-5)]

| 终止程序运行 | 终止程序运行。 |
| [图片上传中...(image-bee657-1545903960442-4)]

| 查看断点 | 可以查看所有的断点,管理与断点配置 |
| [图片上传中...(image-79a94c-1545903960442-3)]

| 禁用所有断点 | 切换所有断点的状态(启用/禁用),禁用后,程序就不会触发断点。 |
| [图片上传中...(image-ddc7f9-1545903960442-2)]

| 获得线程堆栈 | 显示线程的相关信息 |
| [图片上传中...(image-46887d-1545903960442-1)]

| 恢复布局 | 恢复到原始布局 |
| [图片上传中...(image-c2a107-1545903960442-0)]

| 设置 | 调试的相关配置,比如是否显示执行方法后的返回值 |

  • C区帧调试窗口

这里的帧指的是:堆栈帧,一种用于「存储数据」和「部分过程结果」的数据结构; 每次调用方法在堆栈中都会占用一部分内存,单位是,随着方法调用而创建。 每个堆栈帧中包括了:「传入参数」、「返回地址」、「局部变量」以及「对程序调试提供支持的信息」。一个线程包括多个堆栈帧。

[图片上传中...(image-62e229-1545903960444-28)]

查看工具那里可以以上下顺序切换的方方式查看帧(鼠标直接点击也可以),最右侧的漏斗图标 点击后可以过滤掉:「非本应用的帧」。另外,你还可以右键堆栈帧,添加「步进过滤器」、 「导出线程」或「自定义线程显示」。

  • D区变量区

在这个区域可以看到堆栈帧中当前所有的数据(方法参数、本地变量、实例变量)。 右键某个变量,可以进行「设置\复制变量值」,「跳转到变量在代码中的位置」等操作。 一个常用的操作:选择「Add to Watches」,单独监视这个变量的变化。

  • E区监视窗口

除了前面这种右键添加监视的方法外,你还可以直接在E区点击「+」进行添加。

[图片上传中...(image-ee8d53-1545903960444-27)]

不止监控变量,还支持监控表达式,比如上面的i+1。 关于Android Debug调试的基本操作大概就这些,多去实战中历练巩固吧!


3.Android Wifi 无线调试

其实还是要先电脑这个也非常简单,安装一个「ADB WIFI」的插件,安装后重启:

[图片上传中...(image-d8655c-1545903960444-26)]

然后把APP的调试模式为「Usb Device

[图片上传中...(image-345d86-1545903960444-25)]

手机连接电脑,依次点击AS的菜单栏:「Tools」->「ADB USB TO WIFI 」,然后左下角会出现:

[图片上传中...(image-2c3b15-1545903960444-24)]

一般来说,要扫描好久,建议自己看下手机ip,然后通过adb命令进行链接,示例如下:

adb connect 10.1.7.200:5555

# 出现下述信息代表连接成功:
connected to 10.1.7.200:5555
复制代码

连接成功后就可以拔掉数据线,进行无线调试了。


4.利用Network Profiler抓包

Android Profiler是AS 3.0后引入的性能分析工具,而Network Profiler是其中一个用于网络分析的工具, 利用它我们直接抓包,而不需借助第三方的抓包工具(比如Charles)进行分析调试。 比较简单,界面如下:

[图片上传中...(image-711571-1545903960444-23)]

利用它可以进行很方便的抓包操作。


关于Android程序调试的东西肯定不止这些,上述的算是基本功吧。 有更多调试技巧欢迎在评论区留言~谢谢

你可能感兴趣的:(# 逮虾户!Android程序调试竟简单如斯)