运行这个ArcGIS Android程序
已经费了半天劲儿配环境、建工程,还看了一大段植入广告,真累啊……是时候需要看点实在的东西了!现在,让我们运行“AgsSampleHelloWorld”。
图 14 调试Android程序
和一般的Java程序类似,这里选择运行类型为Android Application。一个Android程序想要运行,显然还需要一个模拟器或者真实的设备,如果使用模拟器,那么可以选择刚刚新建的AVD:
图 15 选择模拟器
第一次启动模拟器会花费比较多的时间,当成功启动后,你可以看到“AgsSampleHelloWorld”工程运行的结果,虽然看不到有什么特殊的东西,但是上面曾经提到的“HelloWorld Sample”是不是如愿以偿地出现在了标题位置?
图 16 在Android模拟器上运行Hello World程序
另外,现在已经有一个地图显示了出来,想来这里已经有一个地图控件并加入了一个地图服务,现在,就让我们看看这个“AgsSampleHelloWorld”到底怎么显示这个地图的。
图 17 Hello World程序的调试选项
从“AgsSampleHelloWorld”工程的调试选项中可以看到,在我们运行程序时,程序会运行默认的Activity,在上一节中由于时间关系,并没有对Activity展开叙述,这里再插播一小段Android Activity的内容。
一个Activity就是Android程序呈现给用户的一个界面,所有和用户的交互都在Activity中发生,从某种程度上讲Android的Activity类似一个Windows程序的一个窗体。关于Activity更详细的内容,可以参考这里:http://androidappdocs-staging.appspot.com/reference/android/app/Activity.html。OK,插播结束。
当我们运行“AgsSampleHelloWorld”程序时,实际运行了默认的Activity(com.esri.arcgis.android.sample.HelloWorld),这个Activity的源代码如下:
package com.esri.arcgis.android.samples;
import android.app.Activity;
import android.os.Bundle;
import com.esri.android.map.MapView;
public class HelloWorld extends Activity {
MapView map = null;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
map = (MapView) findViewById(R.id.map);
Object init = getLastNonConfigurationInstance();
if (init != null) {
map.restoreState((String) init);
}
}
/** Called by the system, as part of destroying an activity due to a configuration change. */
public Object onRetainNonConfigurationInstance() {
return map.retainState();
}
}
当运行一个Android的程序,并第一次调用某个Activity时,首先会调用其onCreate方法(详见Activity生命周期),在onCreate方法中,先做的一件事情是下面这句代码:
setContentView(R.layout.main);
这个setContentView方法的作用是根据一个XML格式的布局文件,生成真正的Activity的对象。对于这个“R”我们在上面已经介绍过了,”R.layout.main”对应的资源就是“res/layout”目录下的“main.xml”这个文件定义的布局(这个布局文件有点类似Flex的MXML或Silverlight的XAML,是不是?)。让我们来看看这个“main.xml”的内容:
<?xml version=<i>"1.0" encoding="utf-8"?>
<com.esri.android.map.mapview><p>xmlns:android=<i>"http://schemas.android.com/apk/res/android"</i></p> <p>android:id=<i>"@+id/map"</i> android:layout_width=<i>"fill_parent"</i></p> <p>android:layout_height=<i>"fill_parent"</i></p> <p>initExtent=<i>"-1.3296373526814876E7 3930962.41823043 </i><i> <br></i><i>-1.2807176545789773E7 4201243.7502468005"</i>></p> <p><com.esri.android.map.ags.arcgistiledmapservicelayer></com.esri.android.map.ags.arcgistiledmapservicelayer>url=<i>"http://services.arcgisonline.com/ArcGIS/rest/services/</i><i> <br></i><i>World_Street_Map/MapServer"</i>/></p> <p></p></com.esri.android.map.mapview>
这个布局的根组件就是MapView[1],MapView是基于Android中ViewGroup(可以作为其它View或ViewGroup的容器)的一个类,ArcGIS Android API中使用MapView作为地图的容器,这和很多ArcGIS API中的Map、MapControl类的作用是一样的。
在MapView中,随后又添加了一个ArcGISTiledMapServiceLayer图层,其url属性对应到了某个切片地图服务的REST接口上,可以看到,这里的定义和很多ArcGIS Web上的API是一致的。
MapView有个属性是android:id,这个属性值为“@+id/map”,这定义了在这个xml中的MapView最后将会被解释为一个id为“map”的MapView对象,因此,我们可以回头从“HelloWorld.java”源文件中看到这样的代码:
map = (MapView) findViewById(R.id.map);
在Java代码中,使用findViewById方法就可以获取到当前Activity中的MapView对象,甚至其它任意的View对象。
到这里为止,运行这个ArcGIS Android程序的Activity,然后根据XML定义的布局,生成MapView对象并添加一个ArcGISTiledMapServicesLayer,整个Hello World内部的过程就结束了,最后显示出来的效果就和我们在这个小节开始图 16展示的一样。
[1]http://help.arcgis.com/en/arcgismobile/10.0/apis/android/api/com/esri/android/map/MapView.html