【IT168 技术文档】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 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的真正原因。
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的原因吗?
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 <<<
I/DEBUG ( 641): cannot get registers: No such process
I/DEBUG ( 641): signal 11 (SIGSEGV), fault addr 0000000c
I/DEBUG ( 641): r0 00000000 r1 44c6dd34 r2 00000001 r3 00000024
I/DEBUG ( 641): r4 00000000 r5 00000024 r6 00000001 r7 41048fd8
I/DEBUG ( 641): r8 44c6dd70 r9 41048fd0 10 41048fc0 fp 44c6dd6c
I/DEBUG ( 641): ip 805e3678 sp 44c6dd00 lr afe12583 pc afe122e4 cpsr 20000030
I/DEBUG ( 641): #00 pc afe122e4 /system/lib/libc.so
I/DEBUG ( 641): #01 pc afe12580 /system/lib/libc.so
I/DEBUG ( 641): stack:
结束语
好了,到目前为止我们已经知道了如何搭建平台,启动模拟器,创建工程,查看log分析程序出错原因。还在等什么呢,发挥你无穷的创造力和想象力,投入到OMS应用开发中来吧。
