Android调试工具介绍
一、DDMS
1, Logcat:
在log窗口中,每条信息包含:
(1)Level –表示信息的类别,分为V,D,I,W,E五种,根Log.java中函数对应:
V:verbose,显示全部信息;D:Debug,显示调试信息;I:Info,显示一般信息;W:Warming,显示警告信息;E:Error,显示错误信息。
(2)Time:表示执行的时间。
(3)PID:表示程序运行时的进程号。
(4)TID:表示线程号。
(5)application:应用程序名。
(6)tag:标签。
(7)text:表示一些具体信息。
2,Dump Heap信息(下图红色线标记的按钮):
内存检测工具,检测一个进程的内存变化。
具体操作步骤:
(1) 选中要检测的进程后,Heap按钮会由灰色变为可用。
(2) 点击updateHeap,打开heap视图,然后点击CauseGC。
(3) 操作应用,会看到HeapSize,Data Object值的变化。
(4) 点击DumpHprof file文件,自动保存后缀是.hprof的文件。
保存的.hprof要用hprof-conv.exe转一下才能用mat工具打开;
在Eclipse中通过ADT保存的.hprof可以直接打开。
hprof-conv.exe的用法:
hprof-conv.exe –zres.hprof dest.hprof
代码中添加log,保存dumphprof数据:
android.os.Debug.dumpHprofData(path);
通常定位内存问题流程:先是使用Memory Monitor观察程序是否经常性的发生gc事件,发生gc就会有相应的gc日志;如果有经常gc,利用Heap Viewer来帅选可疑对象,这时可能用到mat工具;最后借助Allocation Tracker确定发生问题的代码位置,Allocation tracker可以获取各个对象的分配情况,包括时间顺序、线程号、对象创建时的调用堆栈等。
3, TraceView数据的采集-method profiling
如下图的红色划线的按钮。
使用方法:
(1)选中要采集数据的进程,点击updatethreads按钮
(2)点击stopmethod profiling按钮,会保存一个.trace的文件,DDMS自动触发traceview工具浏览采集到的数据。
也可以在代码中通过函数来实现,在一段关键代码前调用:Debug.startMethodTracing("traceTest");
在关键代码后调用:Debug.stopMethodTracing();
这两个函数运行过程中将采集这段时间内该应用所有线程的函数执行情况,并把数据保存到一个后缀.trace的文件中。
文件存储的路径:data/media/0/Android/com.android.gallery3d/files/
4, 收集Android关键子系统的运行信息 –systemtrace
如下图红色圆圈标记的按钮。
对应代码中的函数调用:
Trace.java中函数,如:
public static void traceBegin(long traceTag, String methodName);
public static void traceEnd(long traceTag);
二,内存分析工具:MAT –MemoryAnalyzer
1,打开MAT,选择转化好的hprof文件,可以看到如下视图:
2,其中有一项:Leak Suspects泄漏怀疑点,这个是根据对象占的比例列出的可能的泄漏点,不一定是实际的泄漏点。
* public void onCreate() {
* if (DEVELOPER_MODE) {
* StrictMode.setThreadPolicy(new {@link ThreadPolicy.Builder StrictMode.ThreadPolicy.Builder}()
* .detectDiskReads()
* .detectDiskWrites()
* .detectNetwork() // or .detectAll() for all detectable problems
* .penaltyLog()
* .build());
* StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}()
* .detectLeakedSqlLiteObjects()
* .detectLeakedClosableObjects()
* .penaltyLog()
* .penaltyDeath()
* .build());
* }
* super.onCreate();
* }
2, Histogram,统计了每个对象的个数;
Dominator Tree,列举了程序中最占内存的对象。
这2个视图中都可以支持正则表达式搜索具体的类名字。
下图是直方图的界面:
搜索具体对象的视图:
右键点击一行à选择:Merge Shortest paths To GC Rootsà选择exclude weak/soft.references
展开查看是不是有对象被GCroot关联到。
支配树的分析跟这个是类似的。
3,数据对比,以直方图为例,在底部的OverViewPane下,右键选择:Add to Compare Basket ,
然后点击CompareBasket面板右上角“!”按钮,得到比较结果,如下图:
通过上面红圈的菜单,可以选择不同的比较选项。
三,systrace性能数据采集和分析工具
收集Android子系统的运行信息。
\sdk\platform-tools\systrace\systrace.py
通常用命令行形式来生成数据文件,如下图执行红色划线部分命令,抓取结束后会生成trace.html文件:
其中,最后面的一些参数指定要收取那些系统的运行信息:
gfx – Graphics
input – Input
view – View
webview –WebView
wm – WindowManager
am – ActivityManager
audio – Audio
video – Video
camera –Camera
hal – HardwareModules
res – ResourceLoading
dalvik –Dalvik VM
rs –RenderScript
sched – CPUScheduling
freq – CPUFrequency
membus –Memory Bus Utilization
idle – CPUIdle
disk – Diskinput and output
load – CPULoad
sync– Synchronization Manager
生成的trace.html文件,用chrome浏览器打开,
左边区域有cpu信息,Alters,Frames信息,一些用户进程的跟踪等;
右边区域是每一个帧的信息;
当选择一帧后按M键可以高亮这帧,左下角会有这一帧的详细信息。
选中Alters的视图
如下图是一个方法执行时间过长的警告:
这里可以看到问题的描述,
还有调度延迟的警告:
选中Frames的视图,分别用红,黄,绿来区分每一帧绘制时的性能
如下图是选择(红色)一帧的信息:
可以看到它的绘制时长,跟这帧相关的警告,存在的调度问题,方法执行时间过长问题,
展开详细信息:
可以看到这帧的绘制耗时是85ms,大大超过保证平滑的16ms。
下图是一个调度延迟导致渲染过慢的问题
调度延迟就是这个线程很长一段时间内没有分配到cpu来做运算,比如选这一帧中时间最长那块,来得到更详细的信息。
下图是这一帧中较长那块的详细信息:
其中Wall Duration:是这一块从开始到结束的时间;
CpuDuration:是实际cpu在处理这一块消耗的时间。
这2块时间差距很大,就去看下这个过程中cpu干嘛去了。
如下图是当前cpu的信息:
这里可以看到当前cpu被那个应用那个线程占用了,Systrace是一个概览,要找到具体是什么原因让cpu很忙,就要借助traceview了。
四,traceview.bat
现在不推荐使用这个工具打开traceTest.trace文件,而是使用monitor.bat来代替。
如下是用monitor打开trace的一个截图:
图的上半部分是当前进程中每个线程的执行情况。下半部分是每个方法执行的详细信息。
如下是点击一个方法展开的截图:
其中,Parents是调用这个方法的方法,或者叫父方法;
Children是这个方法中会调用的其他方法,或者叫子方法。
这些方法会包括jdk的,sdk的,native的等等。
如下图是方法运行的详细信息:
其中:Incl Cpu Time是这个方法及子方法占用的总的cpu时间;
Excl Cpu Time是父方法的Incl Cpu Time时间减去每个子方法的Incl Cpu Time时间后的剩余值;
Incl Realtime是方法实际的执行时间;
Calls+RecurCalls/Total某个方法被调用次数+递归调用次数占总调用次数的比例;
Realtime/Call某个方法平均的执行时间;
Cpu time/Call某个方法平均占用的cpu时间。
五,lint.bat代码扫描工具
优化:布局性能,未使用的资源,数组大小问题,manifest错误等。
Android Studio中,通过菜单:AnalyzeàInspect CodeàSpecify Inspection Scope
确定后会执行lint命令。
命令使用方式:
如下图:生成报告截图
如下图:展开上图中红色圈中的异常的详细信息:
六,draw9patch.bat:处理.9格式图片的拉伸。
七,hierarchyviewer.bat查看UI布局结构。
八,tombstone分析静态库中的异常
\prebuilts\tools\gcc-sdk\addr2line
Add2line解析静态库中的行号。
要使用没有去除symbols符号的库,对应的是:
\out\target\product\msm8909\symbols\system\lib这个目录下的库文件,使用方法是:
Tombstone_00文件信息:
addr2line -f -elibart.so 0000000000220fc8
-f是把函数名也打出来,
-e接对应的库,
0000000000220fc8地址信息,
九,StrictMode 开发工具,检测代码中是否有违规操作
主要用于捕获在应用主线程中执行的偶然的磁盘读写,网络访问,当收到UI操作和动画执行时,应该让磁盘读写、网络操作远离主线程。
基本用法:
setThreadPolicy 表示策略应用在指定的线程,
detectDiskReads ,detectDiskWrites 检测磁盘读写,
detectNetwork 检测网络访问。
detectCustomSlowCalls 检测某些方法是否执行缓慢,
detectResourceMismatches 检测资源匹配,
penaltyDialog(),检测到违规行为后,显示一个对话框,
penaltyDeath(), crash掉有违规行为的进程,这个操作是在所有penalties的最后执行,在进程dies之前,依然可以看到log,或者其他的违规行为,
penaltyLog(),检测到违规后,输出系统log,
setVmPolicy ,应用于进程中的所有线程,
setClassInstanceLimit(),设置类实例的上限,
detectActivityLeaks(),检测Activity的内存泄漏,
detectLeakedSqlLiteObjects(),检测数据库实例是否有泄漏,如sqlitecursor或者sqlite object已经finalized了,但是没有closed,
detectLeakedRegistrationObjects(),检测broadcastreceiver,serviceconnection,注册与反注册是否配对使用了。
penaltyDropBox(),违规信息,存入到dropbox中。
十,DropBox,这个服务可以记录Android长时间运行过程中的异常信息
记录系统运行过程中kernel,app,系统进程出现的问题,如crash,anr,what terriable failure,strictmode,lowmem,netstats error,system restart等异常的捕获。
然后在data/system/dropbox下生成相应的.txt异常log,log会显示什么类型的问题,那个进程出现的,及相关的堆栈信息。