前言
正所谓,工欲善其事必先利其器,对于一个程序员来说,IDE就是我们器啊。IDE掌控的越熟悉,工作效率就越高(划水摸鱼的时间更多),所以要想效果更高(摸更多的鱼),就要好好学习如何使用IDE。
作为一个Android
开发是无疑是幸福的,背靠Google
爸爸,加上JetBrain
的加持(JB大法好),所以就有了最完美的(不接受反驳)IDE—Android Studio(下文都以AS简称)
,就是有点吃内存哈😁,当然在16G内存的MBP上这些都不是事。虽然做了3年的Android
开发,对于AS
一直都是只用到一些最基础的操作,很多方便的技巧都没用到,远远没有发挥它的最大优势,所以决定从头好好学习一下如何最大化使用AS
。
正题
作为一个程序员,Debug
调试技能是必不可少的,正好AS
也为我们提供了强大的Debug
功能。所以我们今天就来好好学习一下AS
为我们提供的调试功能。
基于Android Studio 3.6.2学习。
开启调试
我们先来看看工具栏上面的图标:
下面一一解释图片中标注按钮(123568虽然不属于debug
相关知识,顺带说一下):
-
Run按钮:
App
已经运行,显示该图标,点击重新运行App
;App
没有运行,该图片显示为绿色三角形。 -
Apply Change and Restart Activity按钮: 通过重启
Activity
但不重启应用来应用资源和代码更改。通常用于修改了代码或资源文件。 - Apply Code Changes按钮: 尝试仅应用代码更改而不重启任何内容。通常用于只修改了代码,没有修改任何资源。
-
Debug按钮: 开启
Debug
模式。 - Coverage按钮: 待摸索(知道的大佬,告诉我一下)。
- Profile按钮: 后面会单独出一篇文章讲解该功能。
-
Attach debugger to Android process按钮:
App
已经运行中,点击该按钮,选择需要调试的进程即可。 -
Stop按钮: 停止运行
App
。
开始调试
当我们进入调试模式时,AS
底部会显示Debug
窗口,如果 Debug
窗口未打开,请依次选择 View > Tool Windows > Debug。下面我们先来看一张Debug
窗口的总览:
我把整个窗口分为多个区域,
- 菜单显示控制区
- 1区断点管理区
- 2区单步调试区
- 3区堆栈帧线程区
- 4区对象变量观察区
下面一一讲解。
菜单显示控制区
首先说一下最左边的菜单显示控制区,点击按钮,会弹窗菜单,勾上就代表该菜单要显示,图片中勾上所有的菜单了,所以在右边就能看到对应的菜单,如果取消那个菜单,右边对应的菜单也会隐藏。这个菜单显示大家可以跟自己需求选择。
重点来了!!!
1区断点管理区
竖向依次为:
-
Return Android Debugger: 重新进入
debug
模式(App不会重新运行) - Resume Program: 跳到下个断点。
- Pause Program: 暂停运行
- Stop Debugger: 停止断点模式
- View Breadpoints: 查看所有断点(后面会单独讲解)
- Mute Breadpoints: 开启\禁用所有断点
- Get Thread Dump: 获取线程Dump,点击会进入线程Dump界面(后面)
- Setting: 对一些菜单的显示控制
- Pin Tab: 多个程序调试时,固定Tab。作用摸索ing...
下面找重点的来讲解一下:
View Breadpoints:
还是先上图
断点展示区:
展示了所有有断点地方,在这里我们可以快速删除不需要的断点,增加程序运行速度。当然我们还可以添加我们关心的异常,就是常说的异常断点,比如NullPointerException
,点击左上角➕,弹出菜单(如下图),大家可以根据自己的需求去选择不同的类型,这里我们选择Java Exception Breakpoints
,然后在搜索框中输入 NullPointerException
,会模糊匹配,然后选择NullPointerException
就可以加入断点展示区了。
这样当我们代码出现空指针异常的时候,就会断点定位到发生异常的位置,非常方便。当时大家还可以添加其他种类的异常。
菜单设置区:
这个菜单可以点击左侧的断点管理区的View Breakpoints
,还可以右键打断点的红点(如下图)
Enable: 是否开启该断点。
Suspend: 默认情况下,Android 系统会在其访问您分配给观察点的内存块时暂停应用进程。后面
All
表示暂停所有线程,Thread
代表暂停当前线程。可以取消选择此选项,当你取消的时候红色断点会变成黄色,上图可以看到。Condition: 这个非常有用,就是常说的条件断点。一般用在循环里面,比如一个for循环,当i=8的时候,执行某个操作,难道你要循环一遍遍走吗?(我之前就是这么干的😂),其实可以直接在condition里面设置条件,如下图显示
可以看到我们`condition`增加条件的时候,红色断点下面多了个小问号,`num`也直接变成8,不用一步步循环到8了。
'Breakpoint hit' message: 勾上会输出
Breakpoint hit
。Stack trace: 勾上会输出堆栈信息。
Evaluate and log: 常说的日志断点,我们一般喜欢通过写代码打log来观察变量的变化,然后再删掉;这样一是麻烦,二是如果忘记,影响代码的美观性。这时,你就需要日志断点,如下图
这样我们就可以打印我们想看的变量了。
- Remove once hit: 就是停一次就移除,这样我们临时打的断点就不存在忘记取消的问题了。
重重重点来了!!!
2区单步调试区
Debug
窗口上方只给出部分单步调试按钮,不过,我们平时用也够了。为了展示AS
全部的单步调试按钮,我对run
菜单下面的单步调试按钮进行讲解,如下图
Step Over(F8): 单步跳过,要前进到下一行代码(而不进入方法),如果方法内部有断点,会暂停。
Force Step Over: 不论方法中是否有断点,都会直接执行完方法所在代码行的下一步,不会在断点处暂停
Step Into(F7): 单步跳入,如果断点包含子方法则进入方法(不会进入官方类库的方法)。
Force Step Into: 强制单步跳入,在Step Info
的基础上能进入任何方法。
Smart Step Info: 断点处包含两个或者以上方法链式调用,可以选择进入那个方法,包括匿名内部类,lambda表达式也可以,看下图。
这时你可以点击get
或者getAccessToken
方法内部进行调试。
Step Out(⇧F8): 单步跳出,与单步跳入相对,要前进到当前方法之外的下一行。
Run to Cursor: 执行到光标出(中途没有断点)。
Force Run to Cursor: 强制执行到光标出(无论有无断点)。
Drop Frame: 点击该按钮后,你将返回到当前方法的调用处重新执行,并且所有上下文变量的值也回到那个时候。只要调用链中还有上级方法,可以跳到其中的任何一个方法。
Evaluate Expression: 可以输入任何符合语法的计算表达式,包括变量,方法等调用。
- 计算表达式
- 方法调用
3区堆栈帧线程区
3区包含Frames
和Threads
。Frames
可以检查导致遇到当前断点的堆栈帧,和后面4区查看变量有关联。Threads
展示当前进程的所有线程。这个区域我用的很少,更多作用待我摸索,对这个区域玩的6的大佬,可以在评论区分享一下。
4区对象变量观察区
这个区域我们平时也用的非常多,我们需要观察的一些变量值,都在这个区域观察。 相信大家都遇到过,我们写好代码,需要根据接口返回的状态进行不同的操作,但是状态永远只会有一种,我们怎么调试每一种状态,我们的代码业务逻辑走的是对的呢?我之前都是强行写一行代码改状态,然后再删掉(真的很low😂)。现在我们可以用setValue
这个功能来改变变量的值了,和上面的Evaluate改变值类似。
还有有时变量特别多,我们只需要观察某一个变量的值时,可以用Add Watches
。
Google
官网也给我们提供了很多更详细的调试技巧,大家有时间可以看一下。