android studio打断点怎么断点调试

泰晓科技 - 使用 JDB 调试 Android 应用程序使用 JDB 调试 Android 应用程序 创作于
By Huang Tao of
前言自从有了各种 IDE 工具,程序猿调试工作轻松了不少,只要在 IDE 上面点击两下按钮,各种程序运行时的信息全部都显示在屏幕上面,很美好的一件事情,我们都要感谢开发这些 IDE 工具的前辈,是他们让我们的工作变得这么“轻松简单”,但是对于我个人来说,不是很喜欢这些 IDE 工具:第一是因为这类 IDE 工具实在是变化太快,我们要花费很大的时间成本来学习这一类工具,然而当你好不容易熟悉了一种工具之后,别人又出了一种更牛 B 的工具,谷歌从 ADT 切换到 Android Studio 就是如此。第二是因为使用这类工具过程中一旦遇到问题,或者想要增加一种功能往往会使人们不知所措,给人的感觉不够灵活。所以相比使用 IDE 工具来说,我比较倾向于使用命令行工具,虽然原始了一点,但是从里面我们可以学到很多东西,使用起来也更加灵活,今天我们要讲的 JDB 就是一种这样的命令行工具,目前大多数程序员在调试 Android 应用程序的时候,大多选择的是 ADT 和 Android Studio,这两个 IDE 已经为我们集成了很多调试的功能,像打断点、单步调试、dump 虚拟机的堆栈信息等,这些工具很强大,是我们开发过程中不可缺少的,但是有没有想过他们是怎么做到的呢?其实他们也是利用了类似 JDB 的功能,然后以可视化界面显示在人们面前。JDWP 协议介绍首先让我们认识一下什么是 JDWP(Java调试线协议),说白了就是 JVM 或者类 JVM 的虚拟机都支持一种协议,通过该协议,Debugger 端可以和目标 VM 通信,可以获取目标 VM 的包括类、对象、线程等信息,在调试 Android 应用程序这一场景中 Debugger 一般是指你的 develop machine 的某一支持 JDWP 协议的工具例如 Android Studio 或者 JDB,而 Target JVM 是指运行在你 mobile 设备当中的各个 App(因为它们都是一个个虚拟机 Dalvik 或者 ART),JDWP Agent一般负责监听某一个端口,当有 Debugger 向这一个端口发起请求的时候,Agent 就转发该请求给 Target JVM 并最终由该 JVM 来处理请求,并把 reply 信息返回给 Debugger 端。上面这个图是借用别人说明 JVM 的,针对 Android 来说可能不是特别准确,我们来看一下 Android 上面是什么情况,调试的时候我们一般通过 ADB 来连接移动设备,所以上面的 JDWP Agent 在 Android 手机上应该是指 adbd 进程,接着上图:上图说明了使用 DDMS 来跟 App VMs 通信的流程,关于 adb 的使用说明,这里就不详细展开了,可以参见 Google 官方文档。再来唠叨一下 JDWP 协议的报文格式,JDWP 协议中主要有两种报文:Command packet 和 Reply packet,command packet 就是我们上面所说的请求报文,reply 自然就是对 command 的回答。JDWP Packet 分为包头(header)和数据(data)两部分组成。包头部分的结构和长度是固定,而数据部分的长度是可变的,具体内容视 packet 的内容而定。Command packet 和 reply packet 的包头长度相同,都是 11 个 bytes.Command packet 的 header 的结构![JDWP-Command-Packet-Header][4]
Length 是整个 packet 的长度,包括 length 部分。因为包头的长度是固定的 11 bytes,所以如果一个 command packet 没有数据部分,则 length 的值就是 11。Id 是一个唯一值,用来标记和识别 reply 所属的 command。Reply packet 与它所回复的 command packet 具有相同的 Id,异步的消息就是通过 Id 来配对识别的。Flags 目前对于 command packet 值始终是 0。Command Set相当于一个 command 的分组,一些功能相近的 command 被分在同一个 Command Set 中。Command Set 的值被划分为 3 个部分:0-63: 从 debugger 发往 target Java 虚拟机的命令64 – 127: 从 target Java 虚拟机发往 debugger 的命令128 – 256: 预留的自定义和扩展命令Reply packet 的 header 的结构![JDWP-Reply-Packet-Header][5]
Length、Id 作用与 command packet 中的一样。Flags 目前对于 reply packet 值始终是 0×80。我们可以通过 Flags 的值来判断接收到的 packet 是 command 还是 reply。Error Code 用来表示被回复的命令是否被正确执行了。零表示正确,非零表示执行错误。Data 的内容和结构依据不同的 command 和 reply 都有所不同。比如请求一个对象成员变量值的 command,它的 data 中就包含该对象的 id 和成员变量的 id。而 reply 中则包含该成员变量的值。JDB 的使用方式上面说了这么多,其实都是为了讲 JDB 的使用原理做的铺垫,JDB 其实是 JDWP 协议中所讲的 Debugger,它运行在 develop machine 上面,它和移动设备上面的 App VMs 通过 JDWP 协议来通信,JDB 一般位于你的 JDK 安装目录下面,可以直接运行,因为 JDB 和移动设备必须通过 ADB 来沟通,所以在 Android 上面使用 JDB 之前必须做一些配置:通过 adb jdwp 列出移动设备上面可以执行 JDWP 协议的进程 ID。通过 adb forward tcp:123456 jdwp:pid (第一步所得到的 PID )设置使用 123456 端口来和移动设备上面的App VMs(其实是 adbd)来通信。执行 jdb -attach localhost:123456 将 jdb attach 到本机的 123456 端口。这样一个 JDB 到移动设备 App VMs 的连接就成了,可以使用 JDB 提供的各种命令来和 App VMs 交互。JDB 的使用示例使用 adb shell ps | grep com.android.settings 来得到 settings 进程的 pid 号为 3107执行 adb forward tcp:12345 jdwp:3107执行 jdb -attach localhost:12345 执行完上面三步之后,jdb 与设置 App 之间的连接就建立好了。执行 jdb 命令 classes,得到设置 App 当中所有的类列表。![JDB Classes][6]
我们感兴趣的是 com.android.setting.Settings 这个类,所以我们继续使用 jdb 命令 methods 来查看这个类拥有哪一些方法。![JDB Methods][7]
假设我们想在 com.android.setting.Settings 这个类的 onCreate 这个方法中添加断点,那么我们执行 stop in com.android.setting.Settings.onCreate(android.os.Bundle) 在这个方法中设置断点,然后我们打开设置 app,jdb 会提示我们断点命中,同时告知我们哪个线程,具体的方法、哪一行等信息。执行 next 命令,使代码执行到下一行。执行 step 命令,使代码单步执行。执行 run 命令,使程序跳过断点继续执行。![JDB Run][8]
JDB 的命令列表** 命令列表 **connectors — 列出此 VM 中可用的连接器和传输run [class [args]] — 开始执行应用程序的主类threads [threadgroup] — 列出线程thread — 设置默认线程suspend [thread id(s)] — 挂起线程 (默认值: all)resume [thread id(s)] — 恢复线程 (默认值: all)where [ | all] — 转储线程的堆栈wherei [ | all]– 转储线程的堆栈, 以及 pc 信息up [n frames] — 上移线程的堆栈down [n frames] — 下移线程的堆栈kill
— 终止具有给定的异常错误对象的线程interrupt — 中断线程print
— 输出表达式的值dump
— 输出所有对象信息eval
— 对表达式求值 (与 print 相同)set
— 向字段/变量/数组元素分配新值locals — 输出当前堆栈帧中的所有本地变量classes — 列出当前已知的类class
— 显示已命名类的详细资料methods
— 列出类的方法fields
— 列出类的字段threadgroups — 列出线程组threadgroup
— 设置当前线程组stop in .[(argument_type,...)] — 在方法中设置断点stop at : — 在行中设置断点clear .[(argument_type,...)] — 清除方法中的断点clear : — 清除行中的断点clear — 列出断点catch [uncaughtcaughtall]
— 出现指定的异常错误时中断ignore [uncaughtcaughtall]
— 对于指定的异常错误, 取消 ‘catch’watch [accessall] . — 监视对字段的访问/修改unwatch [accessall] . — 停止监视对字段的访问/修改trace [go] methods [thread] — 跟踪方法进入和退出。 — 除非指定 ‘go’, 否则挂起所有线程trace [go] method exitexits [thread] — 跟踪当前方法的退出, 或者所有方法的退出 — 除非指定 ‘go’, 否则挂起所有线程untrace [methods] — 停止跟踪方法进入和/或退出step — 执行当前行step up — 一直执行, 直到当前方法返回到其调用方stepi — 执行当前指令下一步 — 步进一行 (步过调用)cont — 从断点处继续执行list [line numbermethod] — 输出源代码use (或 sourcepath) [source file path] — 显示或更改源路径exclude [, ... | "none"] — 对于指定的类, 不报告步骤或方法事件classpath — 从目标 VM 输出类路径信息monitor
— 每次程序停止时执行命令monitor — 列出监视器unmonitor &monitor#& — 删除监视器read
— 读取并执行命令文件lock
— 输出对象的锁信息threadlocks [thread id] — 输出线程的锁信息pop — 通过当前帧出栈, 且包含当前帧reenter — 与 pop 相同, 但重新进入当前帧redefine
— 重新定义类的代码disablegc
— 禁止对象的垃圾收集enablegc
— 允许对象的垃圾收集!! — 重复执行最后一个命令
— 将命令重复执行 n 次`# ` — 放弃 (无操作)help (或 ?) — 列出命令version — 输出版本信息exit (或 quit) — 退出调试器: 带有程序包限定符的完整类名: 带有前导或尾随通配符 (‘*’) 的类名: ‘threads’ 命令中报告的线程编号: Java(TM) 编程语言表达式。支持大多数常见语法。
可以将启动命令置于 “jdb.ini” 或 “.jdbrc” 中 ,位于 user.home 或 user.dir 目录下。参考资料 Read More:本作品由
创作,采用
进行许可。未经授权,谢绝商业使用!3.69¥9.68¥
赏微信扫码,打赏一下!& 2010 ~ 2017 泰晓科技 |手机签到经验翻倍!快来扫一扫!
Android Studio在调试时,修改变量的值
34浏览 / 0回复
本经验介绍在使用Android Studio调试时,修改变量的值。如何新建Android工程可参考经验:/article/ab4c724e67f9bc9.html方法/步骤步骤1、启动Android Studio步骤2、假定有个求和的函数,如图:步骤3、在求和函数名处设置断点,如图:步骤4、注:由于函数体只有一行,在函数体内设置断点将看不到变量。步骤5、启动调试。步骤6、点击工具栏的调试按钮、或者菜单"Run"-"Debug 'xxx'"、或者快捷键。步骤7、单步执行,进入函数体内,如图:步骤8、此时可以在“Variables”窗口中,看到两个变量的值。步骤9、在“Variables”窗口中,选择需要修改的变量,然后右键,选“Set Value..."。如图:步骤10、此时输入想修改的值,如图的例子,然后按回车就成功修改变量的值了。步骤11、修改之后的变量的值,如图:
您需要登录后才可以回帖&&&|&&&&&
用户名/注册邮箱/注册手机号
其他第三方号登录[Android Studio 权威教程]断点调试和高级调试
有人说 的调试是最坑的,那我只能说是你不会用而已,我可以说Android Studio的调试是我见过最棒的。
好了开始写一个简单的调试程序,我们先来一个for循环
for (int i = 0; i & 10; i++) {
//获取当前i的值
int selector =
//打log查看当前i的值(此步多余,实际开发请忽略)
Logger.e(&for当前的i的值:& + i);
//调用方法
stepNext(i);
设置断点(点击红点位置添加或取消断点)
点击debug模式运行vcD4NCjwvYmxvY2txdW90ZT4NCjxwPjxpbWcgYWx0PQ=="这里写图片描述" src="/uploadfile/Collfiles/48.png" title="\" />
查看调试面板
一、简单调试
1. step over:一步步往下走
当前程序运行的位置,我们看到i的值已经在程序代码中展示出来了,黄色的代码处,这个是AS的功能,对于我们调试来讲,这简直是非常大的福利了。
点击单步调试按钮或按快捷键F8,看看效果。这里我们看到selector变量的值已经出来了selector:0,我们在看看黄色位置i的当前值是0。
这时我们继续F8,我们切换到logcat查看日志,我打印出的i的值是0,
我们在切回道Debugger面板,可以看到Variables显示面板中,有i的值是0,selector的值是0。以及我们可以看到Frames控制面板中可以显示出当前程序的位置在:onCreate():28,第28行。
2. step into:看到方法往里走
比如我们的for循环当中调用了一个stepNext(int i)方法,当我们走到这里想看看这个方法里面的运行过程的时候我们可以这样,当走到这个方法的时候我们可以按下F7,或者如下图的图标。
这时就走到了stepNext方法当中。
在这里打印了一个log,我们再按一下F8我们来看看Logcat, 这里我打印的log都是为了做教程用,调试我们就不用打log了直接看显示面板就OK了
3. force step into :所有方法看完整
这个是可以看到你所调用的所有方法的实现会让你跟着它走一遍,研究使用非常方便
4. step out :有断点下一个,走完断点继续走
这里如果我们的一个流程当中,包括调用的方法,如果有断点走到下一个断点,如果没有断点,而是在一个调用的方法当中,会跳出这个方法,继续走。
这里理解比较难,举个例子:
(上图)我现在程序位置在第一个断点位置(24行),我调用的stepNext方法中也有一个断点,此时我按下step out按钮会走到stepNext中的断点处(39行)我此时如果再按一下step out 会走到stepNext方法的调用出的下一个可执行代码(30行)
(上图)如果我现在程序位置在stepNext的方法中,如果我此时按下step out,会走到stepNext方法的调用出的下一个可执行代码(30行)
5. run to Cursor :下个断点我们见
这里的意思就是说,会很快执行到下一个断点的位置,而且可以静如任何调用的方法
二、高级调试
1. 跨断点调试
如果我们设置了多个断点,现在我们需要直接跳转到下一个断点,那么直接点击下图就可以了
2.观察变量
如果我们想观察1个或者几个变量的值的变化,如果我们在Variables显示面版中观察如果我这里有太多太多的自定义变量和变量了,那么就难观察了,我们可以做如下操作:
点击Watches,点击+号,然后输入变量的名称回车就OK了,而且会有历史记录哦
如果变量名比较长我们可以这样:
选择[Variables]中的变量名然后点击[右键],选择[Add to Watches],然后Watches面板中就有了
3.设置变量的值
在程序中有很多的条件语句和循环语句,调试也是比较耗时的,我们可以通过快速设置变量的值来加快调试速度,我们可以做如下操作:
选择[Variables]中的变量名然后点击[右键],选择[Set Value..]或者选择之后直接F2(如上图)(下图为Variables面板)
4.查看断点
点击之后我们可以看到所有的断点,以及位置代码,也可以设置一些属性
5.停止调试
要注意的是这里的[停止调试]不是让程序停止,而是跳过所有调试
到这里我们的Android Studio的断点调试和高级调试就完毕了。
有兴趣的童鞋可以关注我的Blog,我的专栏会持续更新Android Studio 教程,以及2015 I/O大会上的NDK的配置和编译,我也全部会分享给大家。
并且我收到了CSND 的讲师邀请,后期我会把这些Android Studio的使用教程录制成视频发布在CSDN学院。
* --------------
* 欢迎转载
转载请注明
* --------------
* 如果对你有帮助,请点击|顶|
* --------------
* 请保持谦逊 | 你会走的更远
* --------------
* @author zsl
* @github /yy
* @blog http://blog.csdn.net/yy输入关键字进行搜索
1.编译&运行(CMD+F9/Control+R)
写完代码当然想运行下看看效果,立马按下Control+R即可编译加运行。如果你不想运行只想编译的话就按CMD+F9,如果有错误会自动打开message窗口并列出所有错误的地方,一一查看修复即可
2.调试(Control+D)
按下Control+D可以以调试模式运行APP。IDEA的调试功能跟Eclipse比起来可以说强的不止一点半点,突出功能在于其运
行时可以查看其它的API或执行临时编写的代码,比如我得到了一个Context类的实例,那么我可以执行Conext类的任意方法,或者新写一段代码执行,这点是Eclipse无法比拟的。
另外Google在AS中增加了Debug时支持查看bitmap的功能,这对于调试图片具有重大的意义,如下:
Google还新增加了一个实时监控内存的工具叫Memory Monitor(AS特有),放在了窗口的右下角
打开后我们可以选择要监控哪个应用,然后就会实时的显示器内存占用信息,如图所示:
这对于优化内存非常有用,你可以直观的看到在一段时间之内APP内存的变化。如果蓝色区域一直在增高不见下降,那么你的程序就存在内存泄露的问题,一定要重视
在Eclipse中我们已习惯于在Devices窗口中直接在某个进程上点击绿色蜘蛛图标启动debug,这样就免去了重新运行APP的麻烦,如下所示:
AS自然也有这样的功能,点击页面上方“根据进程启动debug”图标后,就会列出可以启动debug的进程,如下图所示
在Eclispe里是在Devices窗口中列出的,这个窗口会列出所有的进程,并没有根据当前项目进行过滤,寻找起来较为麻烦。而AS则做了一个过滤,先显示当前APP所属的进程,点击“Show all processes”后才会显示所有的进程,这样就省了寻找的麻烦了。
使用Lint排除潜在的问题
Lint是Google专门为Android推出的代码检查工具,可以在编译期发现APP中潜在的问题。点开菜单栏中Analyze下面的Inspect Code开始检查代码,项目越大耗时越长。检查完成会自动打开Inspection窗口并显示结果,如下图所示:
我们重点来看一下Android Lint
另外,Eclipse有的DDMS,AS也有,点击屏幕右上角的纯绿色机器人就可以打开DDMS了
CSDN地址:
要回复文章请先或
Android攻城狮}

我要回帖

更多关于 androidstudio打断点 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信