
2.3 调试应用
当构建一个应用后,需要调试它,查看编写的代码是否能正常工作。调试代码最方便的做法就是在代码中使用断点。断点能够帮助你在代码指定的位置暂停运行并查看当前情况(或者当前错误)。现在我们就看看如何在Android Studio中使用断点。
2.3.1 设置断点
使用断点机制可以告诉Android Studio暂停执行代码,这时就可以检查应用的情况。这意味着可以在调试应用时查看变量的值,并且可以查看某行代码是否按照预期执行。
要告诉Android Studio你想在调试时检查某行代码,就必须在该行设置断点。在想要暂停的代码行旁边,单击编辑器的页边,就可以设置断点。设置断点成功后,在页边就会出现一个红圈,并且相对应的那一行会红色高亮显示,如图2-11所示。

图2-11
也可以把光标停在需要设置断点的那一行代码上,然后单击Run | Toggle Line Breakpoint,这样就设置了断点。使用切换(toggle)这个词,是因为你能够以打开这个断点的方法关闭这个断点。单击断点就可以从代码中移除该断点。
注意: Android Studio只会在调试应用时在断点位置暂停——而不会在运行时暂停。所以必须使用其后绘有虫子的绿色箭头按钮(或者选择Run | Debug‘app',或者使用快捷键Shift+F9)。
假设不知道应该在代码的哪一行设置断点,但是想检查当某个特定方法被调用时代码的情况。可以选择Run | Toggle Method Breakpoint设置一个方法断点。如图2-12所示,设置了方法断点的方法签名旁边会出现一个带有四个点的红圈。
注意在图2-12左下方区域中,Android Studio报出一个警告,说方法断点会显著地降低调试速度。这是因为方法断点比普通断点在默认状态下要执行更多的操作。在默认情况下,方法断点是从普通断点中分离出来的。Android Studio会在方法被调用时暂停执行,并且它会自动在方法底部设置一个对应的断点并暂停执行(如图2-13所示)。

图2-12

图2-13
注意:设置一个方法断点和在方法签名位置设置一个普通断点是不同的。可以简单地在方法签名位置处单击编辑器的页边设置普通断点。但是这个断点只会在方法执行时触发。而方法断点还会在方法调用结束时自动暂停。
至此,已经介绍了普通断点和方法断点。此外,在本章中你还会了解另外两种断点:临时断点和条件断点。
1.临时断点
当调试大的循环代码或者只想确定某一行代码是否被执行时,临时断点是非常有用的。要设置临时断点,只需要把光标移动到想要暂停的代码位置,然后选择Run | Toggle Temporary Line Breakpoint。这时在编辑器页边会出现一个里面包含数字1的红圈(当设置了如图2-14所示的条件后)。

图2-14
红圈中的1表示Android Studio只会在第一次代码执行到这里时暂停。此后,这一行代码就会在没有断点设置的状态下执行。如果想调试循环中的某一行代码,但又不希望每次执行到这一行时都停止,使用临时断点就非常有用。
然而,假设想判断循环中的某一行,只有当一个特定的变量值为true(或者类似复杂的情况)时被执行。这种情况下,条件断点是不错的选择。
2. 条件断点
条件断点是只有当满足特定条件时Android Studio才暂停的断点。要设置条件断点,首先在想要调试的代码行设置一个普通断点,然后右击普通断点,弹出条件上下文菜单(如图2-14所示)。
在此可设置条件,告诉Android Studio什么时候在该断点暂停。例如,你希望Android Studio仅在变量foo的值为true时暂停在这个代码行,那么只需要在断点处设置条件为:
foo == true
在复杂的代码块中诊断间歇性问题时条件断点是非常有用的。
2.3.2 导航暂停的代码
在调试模式中,Android Studio会在任何设置的断点处暂停。也就是说,只要在能运行到的代码行设置了断点(系统会执行这行代码), Android Studio就会在那行停止运行,直到你让它继续运行。
当Android Studio触发了断点并暂停执行时,在相应代码行旁边的页边中的红圈就会变成一个打钩的圈(如图2-15所示)。

图2-15
当一个断点被触发时,调试窗口就会在Android Studio的底部打开,如图2-16所示。调试窗口中包含了许多工具,可以使用它们在代码中导航。

图2-16
注意导航按钮在调试窗口的菜单栏里。最常用的按钮是StepOver和StepInto。StepOver按钮会直接跳到当前暂停位置的下一行代码。也就是说如果现在暂停在一个方法调用的位置,然后单击StepOver按钮,AndroidStudio就会直接执行方法调用并停留在下一行。但如果那个方法调用抛出异常并且程序无法执行到下一行会发生什么情况呢?在这种情况下,就要使用StepInto按钮。
Step Into会跟随执行代码。因此,如果暂停在一个方法调用的位置并单击Step Into按钮,Android Studio就会跳到函数中并在该函数的第一行代码位置暂停执行。这样在返回到调用代码之前,你就可以逐行跟踪执行该方法内的代码。