看到关羽三下两下就弄出了第一个Android程序,刘备和张飞对其佩服得五体投地。
刘备说:“二弟啊,没想到你年纪轻轻,开发就有如此造诣!”
关羽说:“我以前有过一些java开发经验,开发平台也是用的Eclipse,环境比较熟悉,上手的比较快,但是Android的具体开发还不是很清楚,大家需要共同学习才行呀。”
刘备说:“二弟实在太谦虚,不过我有一事不明啊。”
关羽说:“大哥请讲!”
刘备说:“你这个第一个Android程序HelloAndroid里的Hello是个什么意思啊?”
关羽说:“大哥……这个Hello是……”
还不等关羽说完,张飞就抢道,“唉,大哥,不是我说你,有时间得多学学蛮文,连哈喽你都不知道。哈喽在蛮文里是‘你吃了吗’的意思!”
关羽擦了擦汗,心想,我怎么结拜了这么两个兄弟,真是交友不慎,但嘴上只好说道:“嗯……这个,三弟大体意思上解释的差不多”
张飞激动道:“大哥,我们现在还等什么?赶紧赚钱吧!这个HelloAndroid摆到网上怎么着也得整个十万八万的吧?”
刘备说:“三弟,你想多了。这个你吃了吗Android只是一个最简单的示例程序,本身没有任何用处,连我这个外行人都看出这个应用肯定是没什么人会花钱买的。咱们还是多学习学习,开发一些有用又有趣的应用,这样才能称霸一方!”
关羽说:“大哥所言极是!我们作为初学者,必须先勤学苦练,打好基础才能成为一代技术大牛!”
张飞郁闷道:“我还以为已经学完了呢,原来这是才开始……”
刘备说:“二弟,接下来你不如讲讲这个Eclipse里这些花花绿绿的工具怎么用吧,比如,调试工具之类的,不知这些工具二弟是否会用?”
关羽说:“大哥,你竟然还知道程序需要调试!真让我刮目相看!”
刘备说:“二弟莫要讽刺我,我可是编过草鞋的男人!”
关羽说:“失礼失礼,那我们就来讲讲Android的实用工具吧。”
张飞说:“在这之前我们先要些饭吃吧,刚才竟吃些花生瓜子,不够填肚子哇。”
刘备说:“小二,来三杯咖啡,三碗泡面!听说技术大牛都这么点。”
关羽、张飞二人异口同声道:“还是大哥有内涵!”
1.1.DDMS
Android自带了一个非常好用的调试工具DDMS(Dalvik Debug Monitor Server),提供了诸如,为当前设备截屏、LogCat、查看进程与广播状态信息、模拟来电与短信、模拟位置信息等功能。
张飞:大哥!Dalvik是啥啊? 刘备:哈哈,三弟,这你就不懂了吧……二弟,告诉他! 关羽:Dalvik虚拟机是Google等厂商合作开发的Android移动设备平台的核心组成部分之一。它可以支持已转换为.dex(即Dalvik Executable)格式的Java应用程序的运行,适合内存和处理器速度有限的系统。Dalvik是由Dan Bornstein编写的,名字来源于他的祖先曾经居住过名叫Dalvík的小渔村。 |
DDMS功能及其全面,本书仅对DDMS的主要功能做初步介绍。
1.1.1.初识DDMS
首先让我们了解一下DDMS的基础概念和运行方法。
运行DDMS
DDMS已经集成到Eclipse中,而使用命令行也可以运行DDMS。
l 在Eclipse中 点击Window→Open Perspective(如果没有DDMS则点击Other...)→DDMS.
图3-1 在Eclipse中启动DDMS
l 使用命令行运行
进入tools/ 目录下运行DDMS即可,出现的界面可能与ADT中的稍有不同,但功能基本一致。
DDMS工作原理
在Android上,每一个程序都运行在一个VM(虚拟机)上,因而每一个程序都有一个独立的端口,用于监听和调试。
当DDMS启动时,会与adb相连,并开启一个Device的监听服务。当移动设备上有一个VM的启动或终止时DDMS都会得到通知。
张飞: adb?啊豆包? 关羽:三弟,注意你的素质!ADB全称Android Debug Bridge,可以管理模拟器或设备的端口映射,也可以将apk安装到模拟器或者设备上。
|
第一个VM开始运行后,DDMS就会通过adb获取该VM的pid,与VM的debugger建立连接,并进行通信。DDMS会为每一个VM分配调试端口,第一个可以调试的VM会分配到8600端口,第二个会分配8601端口,依次往后排。DDMS会默认连接到8700端口(the base port),其他VM的信息会被转发到这个端口,这样每次切换设备时就不用更改调试端口了。
如图3-2展示了在eclipse中打开DDMS的典型界面(通过命令行打开的界面可能会稍有不同):
图3-2 Eclipse中DDMS的界面
注意选中的进程com.android.phone,8602/8700表示DDMS正将8602中的数据转发到静态调试端口8700。
关羽:温馨提示!在eclipse中可以通过Window→perference对DDMS的基本属性进行配置
|
DDMS基本操作
Device选项卡如图3-3所示:
图3-3 Device选项卡
在Device的列表中会列出连接到当前计算机的设备(包括虚拟设备与手机),通过在列表中选标签项,可以改变当前监控的进程。在选项卡最上面一排是各个调试工具的开关,包括:Debug Process(调试进程)、Update Threads(更新线程)、Update Heap(更新堆)、Cause GC(引起垃圾回收)、Stop Process(停止进程)、Screen Capture(屏幕截图)。
上图3-3中,我们选择对com.android.alarmclock进行监控,并开启了线程信息显示,而此时在LogCat选项卡中就可以看到该进程的打印信息了。
1.1.2.用DDMS进行内存使用分析
Dalvik虚拟机也使用垃圾回收机制,但这并不意味着我们就可以忽视内存管理,相反在内存受限的移动设备上,更应该关注内存的使用情况。
下面这段代码中存在Java中典型的内存泄露方式,我们将使用DDMS对其内存使用进行分析:
/** @author 关羽 */
public classMemoryTest extends Activity {
/** Called when the activity is first created.*/
//创建一个Vector存储过期引用
Vector<Object> vector = newVector<Object>(1000000);
@Override
public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获得按钮的引用(后面会讲到相关控件)
Button mButton =(Button)findViewById(R.id.button);
// 设置按钮点击事件的监听器
mButton.setOnClickListener(newOnClickListener() {
@Override
public void onClick(View v) { // 处理点击事件
// 使用vector 存储过期引用,造成内存泄露
for (int i = 1; i < 65536; i++) { //共占用大约1MB
Object o = new Object(); // 一个Object占用16Bytes
vector.add(o);
o = null;//释放o的引用
}
}
});
}
}
张飞:呃,哪里内存泄露了? 关羽:存在一个单引用vector,使其中存储的一大批object无法被回收。 刘备:顶楼上的! |
Heap
在模拟器上运行这个程序,打开DDMS,在Device选项卡中,点击UpdateHeap按钮,然后点击Cause GC按钮,打开并观察Heap选项卡,可以从图3-4中看出,当前分配(Allocated)的内存为6.063MB。
图3-4 Heap选项卡-首次运行
在点击一次程序中的MemoryLeak按钮之后,再次进行垃圾回收,结果如图3-5所示:
图 3-5 Heap选项卡- MemoryLeak后
从上图3-5可以看到data object的TotalSize有明显增加,说明有对象创建出来并没有被垃圾回收,也就是出现了内存泄露。而在下方的直方图显示出data object的数量,明确说明了程序中存在许多16bytes的Object。
Allocation
DDMS也可以对内存分配的位置进行监控。运行程序,在Alloction 选项卡中点击,StartTracking按钮,运行完毕后,点击GetAllocations按钮,获得结果。如图3-6展示了memorytest程序分配内存的情况:
图3-6 Allocation选项卡
可以看到,在onClick函数中分配了大量的Java.lang.Object。
通过对内存分配的追踪,可以清楚的看到一个动作引起的内存分配。这对优化代码,评估程序效率很有帮助极其重要。
1.1.3.用DDMS查看线程
在Device选项卡中点击Update Thread按钮,打开并观察Thread选项卡:
图3-7 Thread选项卡
上图3-7所示是对系统进程system_process进行监控的结果,该选项卡提供的重要信息如下:
l Tid
Linux 线程中的ID,会同进程的ID相匹配
l Status
虚拟机线程的运行状态。状态有以下几种:
running 正在执行应用程序
sleeping 执行了Thread.sleep() 方法
monitor 正等待获取一个监听锁
wait 运行Object.wait()中
native 正在执行原生代码
vmwait 正在等待一个虚拟机资源
zombie 该线程已死
init 线程正在初始化 (无法在选项卡中看到该状态)
starting 线程正在启动中 (无法在选项卡中看到该状态)
l utime
执行用户代码的累计时间
l stime
执行系统代码的累计时间
1.1.4.用DDMS模拟手机操作,及位置服务
通过DDMS可以轻松模仿真实手机的功能,比如接听电话,根据选项模拟各种不同网络情况,模拟接受SMS消息、发送虚拟地址坐标用于测试GPS功能等等。这对于测试程序的功能与稳定性有很大帮助。
模拟发送短信
打开Emulator Control选项卡,填好短信内容,点击Send按钮:
图 3-8 准备发送短信
查看模拟器,可以看到有一条新的短信:
图3-9 模拟器上接收的短信
拨打电话与发送短信的操作很相似,在此就不赘述了。
模拟位置信息
打开Emulator Control选项卡,填写模拟位置信息,点击Send按钮:
图3-10 模拟位置信息
1.1.5.使用LogCat
在android中日志包括VERBOSE、DEBUG、INFO 、WARN 、ERROR等5种类型。以上五种信息的严重等级依次升高,在程序发布的版本中只应包含INFO、WARN、ERROR这三种日志信息。
图3-11 LogCat选项卡
通过LogCat选项卡可以查看程序的日志信息,点击右上角的按钮可以对信息进行过滤。在代码中,一般使用如下方法来记录日志:
Log.i(tag,msg); //tag,msg是String类型
关羽:可以使用””+obj的方式,将一个对象通过toString()方法转换为String类型。 |
图3-12 新建LogFilter
为查看方便,通常会在程序中使用特定Tag(标签),与系统日志进行区分。可以新建一个logfilter(日志过滤器)进行过滤。设置方法如图3-12中所示,在对话框中填写需要过滤出得Tag信息。
1.1.6.用FileExplorer查看文件
除了以上这些功能,使用DDMS提供的File Explorer还可以查看、导入导出模拟器中的文件。打开File Explorer选项卡,效果如图3-13所示:
图3-13 File Explorer选项卡
File Explorer选项卡上共有三个按钮,分别是从设备中导出文件、向设备导入文件和删除文件。需要注意的是导入文件路径和文件名不能含有中文。在文件详情后方有该文件或文件夹的权限状态。需要拥有对应的权限才能进行操作。Android的文件权限跟Linux下的权限规则一样。一个文件一共有三个组别:用户、群组、其它,其中每个组包含三种权限:读r、写w、执行x。也就是说一个文件共有9个权限属性。从左往右一到三位是用户,四到六位是群组,七到九位是其它。如上图3-13,data文件夹的权限是rwxrwx- -x,意思是用户拥有读写执行权限,群组拥有读写执行权限,其他拥有执行权限。
张飞:大哥,我咋看不到sdcard目录? 刘备:嘿嘿,这个我知道!嗯,先看看你的模拟器是不是运行了,另外模拟器的配置中是不是有SD卡?实在不成就把Eclipse和模拟器都重启一下看看。 关羽:大哥英明! |
1.2.其它开发工具
除了ADT中自带的工具外,Android当然也有许多第三方开发工具,在这一节我们将对常用的开发工具进行简介。
1.2.1.Android组建界面设计工具DroidDraw
DroidDraw是开源软件,下载地址为http://code.google.com/p/droiddraw/downloads/list。DroidDraw是一个所见即所得的Android界面生成器,如图3-14所示:
图3-14 DroidDraw主界面
使用DroirDraw产生布局文件非常容易,选择要要用的Layout类型,将控件拖拽到屏幕上,摆好位置后,点击Generate即可生成与当前界面对应的XML文件。另外DroidDraw还提供从工程中导入资源文件,将当前界面输出到设备等诸多功能。
1.2.2. Android感应模拟器 SensorSimulator
SensorSimulator是一个比较全面的Android感应模拟工具,可以实时模拟重力、磁场、加速度、等多种感应,另外也可以模拟电池使用情况,与GPS信息。SensorSimulator是开源软件,下载地址为:http://openintents.googlecode.com/files/sensorsimulator-2.0-rc1.zip
SensorSimulator使用方法如下:解压后在bin目录下有apk与jar文件,将apk安装到模拟器上并启动,同时在电脑上运行jar文件。将配置界面上的IP地址,改为Java模拟器中显示的IP地址,如图3-15所示:
图3-15 SensorSimulator配置
点击Java模拟器中的Sensor选项卡,开启想要模拟的感应选项,然后在Testing界面中点击Connect按钮。在Java模拟器中,移动鼠标对虚拟手机进行操作,可以看到在虚拟机上的数据也会有相应改变,如图3-16所示:
图3-16 SensorSimulator使用
1.3.常用Eclipse插件介绍
Eclipse本身只是一个框架平台,但是众多插件的支持使得Eclipse拥有其他功能相对固定的IDE软件很难具有的灵活性。通过安装适当的插件,可以大大提高编程效率,达到事半功倍的效果。
1.3.1.Eclipse插件安装方法
Eclipse插件主要两种安装方法:
l 下载安装包,直接拷贝
将插件的安装包下载到本地。点击Help→Install New Software选中下载的文件即可。
l 在线安装
点击Help→Elipse Marketplace在其中搜索想用的插件。如果不知道需要什么,就去Popular(热门插件推荐)中看看吧。
图3-17 ElipseMarketplace
1.3.2.Eclipse常用插件
SVN插件SubClipse
SubClipse是一个为Eclise IDE添加 Subversion支持的项目。在SubClipse安装完成后,右键点击工程文件,菜单中会增加一个Team选项,用来进行SVN的操作。
图3-18 team菜单
静态代码检查工具FindBugs
FindBugs是一个在java程序中查找bug的程序,它用来寻找代码存在的缺陷。很多我们代码写的不完善的地方,能够优化的地方,FindBugs都能检查出来。例如:未关闭的数据库连接,缺少必要的null check(空节点检测),多余的 nullcheck,多余的if后置条件,相同的条件分支,重复的代码块,错误的使用了“==”,建议使用StringBuilder代替字符串连加等等情况。
在安装完成之后,右键点击工程文件,会增加FindBugs选项,点击FindBugs即可对代码进行检查。
图 3-19 Find Bugs 菜单
AnyEdit
AnyEdit插件主要是提供一些代码编辑管理方面的功能。最方便的是,可以迅速打开文件。在安装完成之后,在Eclipse的ToolBar上会增加一个Open Files按钮,点击即可快速打开文件。
图3-20 Open File按钮
1.4.玄德有话说
张飞:二哥,DDMS有时候看不到设备,咋整啊?
关羽:我也碰到过这个问题,一般尝试以下手段。(1)确认手机驱动安装正确;(2)重新连接手机;(3)尝试在命令行中输入命令 adb kill-server再输入命令adbstart-server 重新启动adb,最后输入命令adb devices;(4)重启eclipse;(5)重启手机;(6)重启电脑。
张飞:二哥,我LogCat怎么木有输出啊?
关羽:打开Device选项卡,在列表中选中你用的模拟器就可以了,如果这样还不成,就点击右上角的Reset adb按钮。
刘备:二哥,还有一个问题,在DDMS中怎么看不到启动程序的进程?
关羽:要确认如果该应用的manifest中设置application属性,如果android:debuggable="false",是没有办法在DDMS中看到进程的。
刘备:阿飞啊,你今天问题好多……
张飞:读者有需求,我就会坚持问下去!