Android是Google公司于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称。而OMS是基于Android为中国移动“深度定制”的移动操作系统。如果你希望使用OMS SDK搭建环境开发应用程序,请阅读这篇文章。这篇文章总结了很多搭建开发环境的常见问题,例如如何连接OMS SDK中的模拟器,如何安装/卸载ADT,如何创建工程,如何查找程序出错的原因等等。
一. SDK包中的工具介绍
SDK是以zip压缩包的形式提供的。解压后你可以看到其中有tools目录,包含许多实用工具,这里简单介绍一下。 http://developer.android.com/guide/developing/tools/有更详细的说明。
 
emulator是phone的软件模拟器,有了它,不需要任何硬件你就可以看到平台的UI,体验平台的各种特性,也可以把你的应用程序放在模拟器上进行测试。emulator可以待参数执行。例如,emulator -wipe-data可以把模拟器的设置恢复到初始状态。emulator -sdcard SD.file可以模拟插入sd卡的情景,前提是先通过tools目录中的mksdcard工具创建一个sd卡影像文件。emulator支持很多参数,如果想进一步了解可以在命令行下输入emulator -h查看详细的帮助。 如果希望得到手机/模拟器的屏幕截图或log,可以使用tools目录下的ddms工具。
aapt是个非常有用的工具,可以获取log,安装应用程序,复制文件等等。adb shell命令提供一个简单的shell环境,你可以登录到手机/模拟器上进行各种命令行操作,就像在一台Linux电脑里一样。不过adb shell的功能比较简陋,你可以安装一个ARM版的busybox( http://benno.id.au/blog/2007/11/14/android-busybox),使用起来更加方便。OMS平台的aapt设置方法跟Android的略有不同,下面就来介绍一下。二. 如何配置adb
Linux下如何使用adb连接到OMS的手机/模拟器?如果是用手机,在手机正常开机后,使用usb线连接手机到电脑,在手机的弹出菜单中选"调试”,再执行下面命令。如果是模拟器则要等模拟器正常启动之后,执行后面两条命令。
sudo ifconfig usb0 192.168.100.1 export ADBHOST=192.168.100.2 adb kill-server
adb ls /如果一切正常的话,这时可以看到adb列出类似下面的内容。
000041ed 00000000 49fffdfc .
000041ed 00000000 49fffdfc ..
000041ed 00000000 49fffdfc Linux
0000a1ff 00000012 49fffdfc bin
0000a1ff 00000012 49fffdfc usr
0000a1ff 00000012 49fffdfc lib
000043ff 0000008c 49fffe44 tmp
...
三. 怎样配置开发环境
下面开始介绍怎么配置开发环境。在OMS平台上开发应用跟Android一样需要使用java。我们推荐使用最新版的Eclipse开发环境,否则安装ADT可能会失败。Eclipse下载地址为 http://www.eclipse.org/downloads/.
安装完Eclipse后,需要安装ADT(Android Development Tools)插件。在Eclipse的Help->Software Updates...菜单中,选择Add Site...,Location填 https://dl-ssl.google.com/android/eclipse/site.xml,然后点击OK按钮开始安装。如果网络连接失败,你可以从别的地方下载adt.zip压缩包,然后在Add Site对话框中选择Archive...开始安装。OMS SDK提供了一个特殊版本的ADT,后面我会加以介绍。
安装完ADT后,需要在Eclipse的Window->Preference中指明OMS SDK所在的目录,也就是你把SDK zip文件解压缩后生成的目录。如图所示
 
创建OMS工程的步骤跟创建Android工程的相同,网上有很多介绍,这里就不再复述了。
如何卸载ADT呢?如果你需要卸载ADT的话,可以在eclipse/plugin目录中查找以下文件,删除就可以了。注意,版本号和日期可能会有变化。
com.android.ide.eclipse.adt_0.8.0.v200809220836-110569.jar com.android.ide.eclipse.common_0.8.0.v200809220836-110569.jar com.android.ide.eclipse.ddms_0.8.0.v200809220836-110569.jar com.android.ide.eclipse.editors_0.8.0.v200809220836-110569.jar   
org.eclipse.ui.views.log_1.0.0.v20080803-1700.jar
如何在你的工程中使用OMS提供的API呢?OMS平台提供了许多特有的API,全都放在oms.jar中。你需要在Eclipse中通过Project->Properties->Add Library来添加。注意一定不要使用External JARs方式。External JARs会把jar文件编译加入到你的apk文件里,会导致编译出错。
 
如何在工程中集成.so库文件呢?如果你的程序使用了JNI native库文件,你需要把这些库文件安装到手机/模拟器的/system/lib目录下,不然程序运行时会出现force close。OMS平台提供了一个特殊版本的ADT,可以让你在工程中加入native库文件。安装了这个版本的ADT后,在用Eclipse的File->New->Android Project菜单新建Android工程时,会有如下的对话框。
 
注意选中Use native libraries.
创建好工程后,在工程的目录结构中会看到"nativelibs”,把你的native库文件复制到armeabi下就可以了,见下图。
 
          
       
四. 调试程序
好了,现在你已经写好了你的应用程序,把它放到模拟器里跑一下看看效果吧。在Eclipse中,点击Run->Run菜单,Eclipse会自动编译安装你的应用到手机/模拟器中。应用编译成功后会生成.apk文件,你也可以用adb install手工安装你的apk文件。如果程序出现force close怎么办?下图展示了一个应用force close时的屏幕截图。
这时你需要使用adb logcat查看系统log。有经验的程序员可以在log中发现很多有用信息。在嵌入式系统中,很多时候没办法调试程序,读log分析问题才是王道。这里我给出一个程序force close时的log。注意看"Shutting down VM"前面的那句话,这个应用需要读取Android market相关的信息,但平台中没有安装Android market,这是导致应用force close的真正原因。
D/dalvikvm(  844): GC freed 13377 objects / 604304 bytes in 248ms
I/ActivityManager(  844): Starting activity: Intent { action=android.intent.action.VIEW data=market://search?q=pname:com.android.wallswitch1 }
D/AndroidRuntime( 3162): Shutting down VM
W/dalvikvm( 3162): threadid=3: thread exiting with uncaught exception (group=0x40010e28)
E/AndroidRuntime( 3162): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 3162): android.content.ActivityNotFoundException: No Activity found to handle Intent { action=android.intent.action.VIEW data=market://search?q=pname:com.android.wallswitch1 }
E/AndroidRuntime( 3162):        at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1472)
E/AndroidRuntime( 3162):        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1442)
E/AndroidRuntime( 3162):        at android.app.Activity.startActivityForResult(Activity.java:2597)
E/AndroidRuntime( 3162):        at android.app.Activity.startActivity(Activity.java:2641)
E/AndroidRuntime( 3162):        at com.android.wallswitch1.wallswitch1$5.onClick(wallswitch1.java:238)
E/AndroidRuntime( 3162):        at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:153)
E/AndroidRuntime( 3162):        at android.os.Handler.dispatchMessage(Handler.java:88)
E/AndroidRuntime( 3162):        at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 3162):        at android.app.ActivityThread.main(ActivityThread.java:3742)
E/AndroidRuntime( 3162):        at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 3162):        at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime( 3162):        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
E/AndroidRuntime( 3162):        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)
E/AndroidRuntime( 3162):        at dalvik.system.NativeStart.main(Native Method)
I/Process (  844): Sending signal. PID: 3162 SIG: 3
I/dalvikvm( 3162): threadid=7: reacting to signal 3
D/ActivityManager(  844): ######  [ap_panic_report] = off
I/dalvikvm( 3162): Wrote stack trace to '/local/log/traces.txt'
再来举一个例子,你能从下面的log中看出这个应用force close的原因吗?
I/ActivityManager(  855): Starting activity: Intent { action=android.intent.action.MAIN flags=0x10000000 comp={com.iflytek.aisound.demo/com.iflytek.aisound.demo.AisoundDemo} }
D/InputMethodManager(  923): static exitContext
D/mountd  (  640): USB_DETECT: msg is 'add@/kernel/uids/10067'
I/ActivityManager(  855): Start proc com.iflytek.aisound.demo for activity com.iflytek.aisound.demo/.AisoundDemo: pid=1162 uid=10067 gids={}
I/Config  (  855): 22222 Input configuration changed: null
D/Focus   (  923): Lose Window focus: "" com.db4o.servo.search.SearchBar$3@43820f78
D/DcdHomeLayout(  923): setDisplayedChild: 1
D/DcdHomeLayout(  923): scroll to (0, 0), this=com.android.borqshome.dcd.DcdHomeLayout$EntryTextLayout@43825be8
D/DcdHomeLayout(  923): height=74 m_scrollingShift=64
D/dalvikvm( 1162): Trying to load lib /sdcard/iflytek/libAisound4.so 0x43876e40
E/MediaPlayer( 1162): constructor
E/MediaPlayer( 1162): setListener
D/dalvikvm( 1162): Added shared lib /sdcard/iflytek/libAisound4.so 0x43876e40
W/dalvikvm( 1162): ERROR: Unable to find decl for native Lcom/iflytek/aisound/Data;.JNICALL Java_com_iflytek_aisound_Data_prepareData (Ljava/lang/String;I)V
D/dalvikvm( 1162): +++ not scanning '/system/lib/libwebcore.so' for 'ContrlInit' (wrong CL)
D/dalvikvm( 1162): +++ not scanning '/system/lib/libmedia_jni.so' for 'ContrlInit' (wrong CL)
D/Focus   ( 1162): Gain Window focus: "" android.widget.EditText@43880570
I/DEBUG   (  641): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  641): Build fingerprint: 'generic/OMS1_0/OMS1_0/:1.0/ohd-stable-114235/eng..20090115.111116:eng/test-keys'
I/DEBUG   (  641): pid: 1162, tid: 1169  >>> com.iflytek.aisound.demo 结束语
好了,到目前为止我们已经知道了如何搭建平台,启动模拟器,创建工程,查看log分析程序出错原因。还在等什么呢,发挥你无穷的创造力和想象力,投入到OMS应用开发中来吧。
收藏 分享 评分
回复 引用
订阅 TOP
ophone
发短消息
加为好友
ophone 当前离线
UID
1
帖子
1321
精华
13
积分
1098
威望
140 点
O币
1860 个
阅读权限
200
在线时间
369 小时
注册时间
2008-11-18
最后登录
2009-5-20
 
O8管理员
帖子
1321
O币
1860 个
2楼
 发表于 5 天前 20:27 | 只看该作者
什么是Dalvik虚拟机?Google于2007年底正式发布了Android SDK, 作为 Android系统的重要特性,Dalvik虚拟机也第一次进入了人们的视野。它对内存的高效使用,和在低速CPU上表现出的高性能,确实令人刮目相看。依赖于底层Posix兼容的操作系统,它可以简单的完成进程隔离和线程管理。每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行。
很多人认为Dalvik虚拟机是一个Java虚拟机,因为Android的编程语言恰恰就是Java语言。但是这种说法并不准确,因为Dalvik虚拟机并不是按照Java虚拟机的规范来实现的,两者并不兼容;同时还要两个明显的不同:
 
Java虚拟机运行的是Java字节码,而Dalvik虚拟机运行的则是其专有的文件格式DEX(Dalvik Executable)。
  
在Java SE程序中的Java类会被编译成一个或者多个字节码文件(.class)然后打包到JAR文件,而后Java虚拟机会从相应的CLASS文件和JAR文件中获取相应的字节码;Android应用虽然也是使用Java语言进行编程,但是在编译成CLASS文件后,还会通过一个工具(dx)将应用所有的CLASS文件转换成一个DEX文件,而后Dalvik虚拟机会从其中读取指令和数据。Dalvik和Android系统Android作为新一代的基于Linux的开源手机操作系统,其系统架构由下而上可以分为以下几部分:
 
Linux内核 本地库 Android运行库 应用框架
应用
 
图表1
如图所示,Android运行库包括两部分:核心库和Dalvik虚拟机。核心库包括了最基本的类库,如data structure, network, Utilities, File system等的,很多实现代码都是来自Apache Harmony项目,主要目的是保证虚拟机的类库能够和Java SE的类库最大可能的兼容,从而降低应用开发者从Java SE阵营转移到Android开发阵营的难度,增加其可用性。Dalvik虚拟机主要是完成对象生命周期的管理,堆栈的管理,线程管理,安全和异常的管理,以及垃圾回收等等重要功能。
Dalvik虚拟机的主要特征Dalvik虚拟机非常适合在移动终端上使用,相对于在桌面系统和服务器系统运行的虚拟机而言,它不需要很快的CPU速度和大量的内存空间。根据Google的测算,64M的RAM已经能够令系统正常运转了。其中24M被用于底层系统的初始化和启动,另外20M被用于高层启动高层服务。当然,随着系统服务的增多和应用功能的扩展,其所消耗的内存也势必越来越大。
归纳起来,Dalvik虚拟机有如下几个主要特征:
专有的DEX文件格式
DEX是Dalvik虚拟机专用的文件格式,而问什么弃用已有的字节码文件(CLASS文件)而采用新的格式呢?
1.一个应用中会定义很多类,编译完成后即会有很多相应的CLASS文件,CLASS文件间会有不少冗余的信息;而DEX文件格式会把所有的CLASS文件内容整合到一个文件中。这样,除了减少整体的文件尺寸,I/O操作,也提高了类的查找速度。
原来每个类文件中的常量池,在DEX文件中由一个常量池来管理,具体方式如下图:
 
图表2
图表3
 
2.增加了新的操作码的支持
3.文件结构尽量简洁,使用等长的指令,借以提高解析速度
4. 尽量扩大只读结构的大小,借以提高跨进程的数据共享
如何生成DEX文件呢?Android系统和Dalvik虚拟机提供了工具(DX),在把Java源代码编译成CLASS文件后,使用DX工具。
 
图表4
DEX的优化DEX文件的结构是紧凑的,然是如果我们还想要求运行时的性能有进一步提高,我们就仍然需要对DEX文件进行进一步优化。优化主要是针对以下几个方面:
 
调整所有字段的字节序(LITTLE_ENDIAN)和对齐结构中的没一个域 验证DEX文件中的所有类
对一些特定的类进行优化,对方法里的操作码进行优化优化后的文件大小会有所增加,应该是原DEX文件的1-4倍。
优化发生的时机有两个:对于预置应用,可以在系统编译后,生成优化文件,以ODEX结尾。这样在发布时除APK文件(不包含DEX)以外,还有一个相应的ODEX文件;对于非预置应用,包含在APK文件里的DEX文件会在运行时被优化,优化后的文件将被保存在缓存中。
基于寄存器相对于基于堆栈的虚拟机实现,基于寄存器的虚拟机实现虽然在硬件通用性上要差一些,但是它在代码的执行效率上却更胜一筹。一般来讲,虚拟机中指令的解释执行时间主要花在以下三个方面:
分发指令 访问运算数
执行运算其中“分发指令”这个环节对性能的影响最大。在基于寄存器的虚拟机里,可以更为有效的减少冗余指令的分发和减少内存的读写访问,如:
 
图表5
虽然Dalvik虚拟机并没有使用目前流行的虚拟机技术,如JIT,但是根据Google的报告,这个功能的缺失并没有另Dalvik虚拟机在性能上有所损失。我们也同时相信,Dalvik虚拟机的性能还有进一步提高的空间。
一个应用,一个虚拟机实例,一个进程每一个Android应用都运行在一个Dalvik虚拟机实例里,而每一个虚拟机实例都是一个独立的进程空间。虚拟机的线程机制,内存分配和管理,Mutex等等都是依赖底层操作系统而实现的。所有Android应用的线程都对应一个Linux线程,虚拟机因而可以更多的依赖操作系统的线程调度和管理机制。
不同的应用在不同的进程空间里运行,加之对不同来源的应用都使用不同的Linux用户来运行,可以最大程度的保护应用的安全和独立运行。
Zygote是一个虚拟机进程,同时也是一个虚拟机实例的孵化器,每当系统要求执行一个Android应用程序,Zygote就会FORK出一个子进程来执行该应用程序。这样做的好处显而易见:Zygote进程是在系统启动时产生的,它会完成虚拟机的初始化,库的加载,预置类库的加载和初始化等等操作,而在系统需要一个新的虚拟机实例时,Zygote通过复制自身,最快速的提供个系统。另外,对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域,大大节省了内存开销。
图表6
应用程序包(APK)被发布到手机上后,运行前会对其中的DEX文件进行优化,优化后的文件被保存到缓存区域(优化后的格式被称为DEY),虚拟机会直接执行该文件。如果应用包文件不发生变化,DEY文件不会被重新生成。
 
 
图表7
Android应用开发和Dalvik虚拟机Android应用所使用的编程语言是Java语言,和Java SE一样,编译时使用Sun JDK将Java源程序编程成标准的Java字节码文件(.class文件),而后通过工具软件DX把所有的字节码文件转成DEX文件(classes.dex)。最后使用Android打包工具(aapt)将DEX文件,资源文件以及AndroidManifest.xml文件(二进制格式)组合成一个应用程序包(APK)。应用程序包可以被发布到手机上运行。