李华明Himi 原创,转载务必在明显处注明:
不少童鞋说个人代码运行后,点击home或者back后会程序异常,若是你也这样遇到过,那么你确定没有仔细读完Himi的博文,第十九篇Himi专门写了关于这些错误的缘由和解决方法,这里我在博客都补充说明下,省的童鞋们总疑惑这一块;请点击下面联系进入阅读:css
【Android游戏开发十九】(必看篇)SurfaceView运行机制详解—剖析Back与Home按键及切入后台等异常处理!html
因为本人如今在一家专职作网游的公司,因此如今须要使用一些方法对现运营的网游代码进行精简和优化,那么就要使用到Android sdk中提供的一款很好的检视工具—Android TraceView、下面先给出对此的解释:而后讲解实现的详细步骤和须要特别注意的一点!java
什么是TraceView?先看下百度出来的解释吧:android
Traceview是android平台配备一个很好的性能分析的工具。它能够经过图形化的方式让咱们了解咱们要跟踪的程序的性能,而且能具体到method。canvas
关于Traceview的使用windows
首先,必须在程序当中加入代码,以便生成trace文件,有了这个trace文件才能够将其转化为图形。api
要添加的代码以下:app
Java代码eclipse
// start tracing to "/sdcard/yourActivityTrace.trace"ide
Debug.startMethodTracing("yourActivityTrace");
// ... // stop tracing Debug.stopMethodTracing();
// start tracing to "/sdcard/yourActivityTrace.trace" Debug.startMethodTracing("yourActivityTrace");
// ... // stop tracing Debug.stopMethodTracing();
Google Dev Guide当中说能够在activity的onCreate()中添加Debug.startMethodTracing(), 而在onDestroy()中添加Debug.stopMethodTracing(),可是在实际的测试时发现这种方式其实并很差用,由于一般状况下咱们的activity的onDestroy()是由系统决定什么时候调用的,所以可能等了很长时间都不会获得这个trace文件。所以决定在onStop()中来调用Debug.stopMethodTracing()。这样当咱们切换到其它activity或者点击home键的时候onStop()就会被调用,咱们也就能够获得完整的trace file。
在运行程序以前,首先要保证咱们的AVD是一个带有SD card的AVD,这样才能使trace文件保存到/sdcard/...当中。运行后能够任意作一些操做,而后点击home键。这是经过DDMS file explore就能够看到/sdcard/目录下有一个trace文件,如今把这个文件copy到电脑上指定的目录,假设是C:/tracefile 目录下。
能够经过命令行来执行traceview,进入tools目录后,执行
traceview C:/tracefile/yourActivityTrace.trace
以后就能够看到图形了,接下来就是按照Google Dev Guide中的解释去分析图形就OK了。
下面来看如何实现以及须要注意的地方:
实现的步骤分为三步:1.必须先在咱们的模拟器中建立sdCard ;2.将咱们的调试代码嵌入工程;3.利用TraceView来观察和分析代码状况;
1.对于建立模拟器的sdCard这里写出两种方式:
第一种:咱们在eclipse中建立avd的时候的时候 在选择api下面有个 Sd Card 的选项,第一项填入建立sdcard的大小便可。
第二种:cmd 命令! 打开cmd 而且cd 到android sdk tool 路径下;(或者在环境变量Path中将sdk tool路径配置上,而后从新打开cmd)
使用 mksdcard -l mycard 1024M F:/mysdcard.img 建立了一个1G的sdcard;
使用 emulator -avd my_android -sdcard F:/mysdcard.img 激活sdcard!
最后在eclipse Preferences-->Android-->Launch加入 -sdcard F:/mysdcard.img (此步骤就是在第一种建立方式中添加sdcard的支持)
备注1:
若是sdcard分配的空间过小,则程序追踪文件就一直记录到sd储蓄卡容量慢为止,因此调试前,要为程序生成一个适当的SD存储卡也较为重要,由于程序运行时间越长,这个追踪文件也就越大。
备注2;
(若是第二种建立方式中的第二部激活出现 emulator: ERROR: the user data image is used by another emulator. aborting,请关闭模拟器,或者进入目录: /Documents and Settings / 用户 / .android /的AVD / *设备* / (好比个人目录是:C:/Documents and Settings/Administrator/.android/avd/android2.0.avd)
而后删去以.lock结尾的文件夹就行(我简单解释下为何要删除这些文件呢,其实.lock是加锁,若是程序崩溃等缘由致使没法清除这些以.lock结尾的文件夹,就会出现这个问题,也就是这个avd的锁没有被释放,致使avd manager觉得这个avd正在使用当中。))
2.将咱们的调试代码嵌入工程
正如咱们百度到的说明同样,在程序运行的开端加上 Debug.startMethodTracing("yourActivityTrace"); 而后在onPause()中调用Debug.stopMethodTracing(); 为何要将结束写在onPause()中而不写在onStop(),那么若是你去看api的话,你会看到,Api中介绍onPause()会在你返回和点击home按键后触发,而onStop()通常是由系统来触发,当该程序处于后台的时候,并且当内存紧张的时候,可能会调用,可是可能永远不会调用到!
备注:要记住当把调试代码加入项目中之后不要当即运行项目,而是必须在AndroidMainfest.xml中定义一条"写入SD卡的权限"那么添加权限的代码以下:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
由于我们的调试代码会在SD卡中生成一个追踪文件,也就是往SD卡中写入了数据,因此须要声明一条权限。这里必须注意哦!
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.himi" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <uses-sdk android:minSdkVersion="4" /> </manifest>
3.运行项目而且退出项目从而获得的追踪文件,利用TraceView来进行分析代码运行情况:
打当正常运行了项目而且点击返回或者home按键就会在 sdcard中生成一个.trace的文件。sdcard 目录 在eclipse下,点击:
windows-show view-other-android-File explorer
右上角的两个箭头,第一个表示从模拟器sdcard导出文件,第二个表示从PC上导入文件到sdcard中、“—”表明删除 .....
而后咱们经过cmd来运行生成的追踪文件 traceview C:/name 追踪文件所在的路径放在C盘,放在C盘之外别的盘的话我这里是没法正常打开traceview的不知道什么缘由。 name 表示生成的.trace文件,cmd的时候不须要输入“.trace”后缀 ;而后会出现TraceView的分析窗口;
【cmd 命令! 打开cmd 而且cd 到android sdk tools 路径下;(或者在环境变量Path中将sdk tool路径配置上,而后从新打开cmd)】
注意1:若是出现一下图片这种内存溢出的问题;
解决方法:到SDK 下的tools 下 找到 traceview.bat 文件,鼠标右键-编辑(或者记事本打开),最后一行替换成这样:
call java -Xms128m -Xmx512m -Djava.ext.dirs=%javaextdirs% -jar %jarpath% %*
注意2:若是出现路径不对的问题:
例如:个人 himi.trace 放在了C盘,那么个人cmd命令是: traceview c:/himi 而后回车!
可是这里要当心,由于 /h 这样可能被认为是转义字符!!!为了不能够尽量不要使用h,n,r,t,等等成为名字的头字母,固然还有一种就能够彻底避免这种问题,例如仍是个人C盘 himi.trace 文件,能够写cmd命令的时候写成: traceview c://himi 嘿嘿~要注意细节。
下面是运行起来的TranceView:
最右上角表示运行程序总共用了多少时间,从traceview画面中咱们看到有各类颜色,每种颜色表明不一样的函数和步骤,那么同一颜色的区域越大,就表明这个步骤运行时间越长,或者看到下面的统计表,明显能够看出除了序列 0 1 是系统函数外,2. 3.函数 占用的时间比较长,那么序列4是个自定义的函数名为 “hot”这个占用了几乎与主线程 主draw的时间同样了,那么确定有问题。固然其实这个方法是我故意写的,就是为了来演示traceview。这个hot函数的代码以下:
/** * @author Himi * @param canvas */ public void hot(Canvas canvas) { for (int i = 1; i < 100; i++) { Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon); canvas.drawBitmap(bmp, i += 2, i += 2, paint); } }
很明显我在故意消耗内存和时间。
那么,在traceview的右半部统计字段中:
Exclusive: 同级函数自己运行的时间
Inclusive 就是说除统计函数自己运行的时间外再加上调用子函数所运行的时间
Name:列出的是全部的调用项,前面的数字是编号,展开能够看到有的有Parent 和Children子项,就是指被调用和调用。
Incl: inclusive时间占总时间的白分比
Excl: 执行占总时间的白分比。
Calls+Recur Calls/Total: 调用和重复调用的次数
Time/Call: 总的时间。(ms)
因此traceview是个很是好的程序监视工具,能够帮助找出程序运行缓慢时的函数,让咱们的代码不断完善和改进!
(欢迎你们订阅本博客,由于咱的更新速度但是很快的~娃哈哈)