<arg value="install" />
<arg value="${out-package}" />
</exec>
</target>
</project>
鉴于你已经理解了如何手动使用build.xml, Android项目的命令行创建,你就可以开始编辑你的项目文件,并创建一个Android Activity。你需要看的第一个文件是main.xml。使用Windows Explorer,在AndroidHelloWorld\res\layout下浏览main.xml。
本节中你会使用Windows命令行接口编辑项目文件。项目文件就是前部分用ActivityCreator.bat的。你会脱离Eclipse,编辑这些文件,并为他们添加代码。
编辑项目文件
用XML编辑器或记事本(如果你没有特定的XML编辑器)打开main.xml。这可以让你编辑文件和删除内部的<TextView/>定义。如下插图所示保存main.xml文件。
保存的main.xml文件其实是一个空壳。这就给了你一个编辑你的<avtivity>.java文件的平台。这个<activity>.java文件在一个有好几层深的目录中,即AndroidHelloWorld\src\android\programmers\guide。
要创建你的Hello World!应用,添加下面几行来创建、设置和使用TextView:
/**Hello World JFD */
/**BEGIN */
/**Create TextView */
TextView HelloWorldTextView = new TextView(this);
/**Set text to Hello World */
HelloWorldTextView.setText("Hello World!");
/**Set ContentView to TextView */
setContentView(HelloWorldTextView);
/**END */
不要忘记在文件开头添加TextView包:
import android.widget.TextView;
完整的HelloWorldCommandLine.java应该是如下插图的样子:
现在你的项目文件就设置好了。你可以编译你的程序并在Android模拟器上运行。
添加JAVA_HOME变量
在你试图编译项目之前,你必须在你的电脑——JAVA_HOME——中位你的JDK添加另一个环境变量。及时该路径已经存在于你的PATH生命,你也应该创建一个名为JAVA_HOME的新变量。
1、 右击我的电脑,选择属性。
2、 在系统属性窗口选择高级选项,并点击环境变量按钮。这样会打开一个环境变量窗口。
3、 双击新建按钮,添加一个名为JAVA_HOME的新变量。该变量的值应该是你的Java SDK的全路径,如下所示:
编译和安装应用
该进行真实测试了。现在你能够编译你的命令行项目了。用ANT编译项目。一旦项目被编译,你就可以在模拟器上安装它了。
用ANT编译项目
在你设置好你的JAVA_HOME环境变量和在PATH生命中创建ANT后,你就可以浏览你的build.xml文件目录,简单地运行ant命令。为你的项目目录打开一个Windows命令提示窗口并运行ant,如下:
如果运行ant出现错误时怎么办 如果当运行ANT时产生错误,不要怕。因为写这本书时Android还在初始发布阶段,部分功能可能需要更改。当你使用新技术时,随处都会有一些小的变更。 当我第一次运行ant编译我的项目时,我就遇到了如下所示的错误:
对于这个问题的研究, Google Android开发者论坛上提供了相当有趣的解决方案:重写build.xml,调整ANT提供的命令。下面就是修改后的build.xml文件,关键变更被加粗了。比较一下这个文件与原始文件,你会发现一些明显的差异。
<?xml version="1.0" ?>
<project name="HelloWorldCommandLine" default="package" basedir=".">
<property name="sdk-folder" value="c:\Android\android-sdk_m5
rc14_windows\android-sdk_m5-rc14_windows" />
<property name="android-tools" value="c:\Android\android-sdk_m5
rc14_windows\android-sdk_m5-rc14_windows\tools" />
<property name="android-framework" value="${android-tools}/lib/framework.aidl"
/>
<!-- The intermediates directory -->
<!-- Eclipse uses "bin" for its own output, so we do the same. -->
<!-- Use full path for output dir - FIX - BLOCK START -->
<property name="outdir" value="${basedir}/bin" />
<!-- Use full path for output dir - FIX - BLOCK END -->
<!-- No user servicable parts below. -->
<!-- Input directories -->
<property name="resource-dir" value="res" />
<property name="asset-dir" value="assets" />
<property name="srcdir" value="src" />
<!-- Output directories -->
<property name="outdir-classes" value="${outdir}/classes" />
<!-- Create R.java in the source directory -->
<property name="outdir-r" value="src" />
<!-- Intermediate files -->
<property name="dex-file" value="classes.dex" />
<property name="intermediate-dex" value="${outdir}/${dex-file}" />
<!-- The final package file to generate -->
<property name="out-package" value="${outdir}/${ant.project.name}.apk"/>
<!-- Tools -->
<property name="aapt" value="${android-tools}/aapt" />
<property name="aidl" value="${android-tools}/aidl" />
<condition property="dx" value="${android-tools}/dx.bat" else="${android
tools}/dx" >
<os family="windows"/>
</condition>
<property name="dx" value="${android-tools}/dx" />
<property name="zip" value="zip" />
<property name="android-jar" value="${sdk-folder}/android.jar" />
<!-- Rules -->
<!-- Create the output directories if they don't exist yet. -->
<target name="dirs">
<mkdir dir="${outdir}" />
<mkdir dir="${outdir-classes}" />
</target>
<!-- Generate the R.java file for this project's resources. -->
<target name="resource-src" depends="dirs">
<echo>Generating R.java...</echo>
<exec executable="${aapt}" failonerror="true">
<arg value="compile" />
<arg value="-m" />
<arg value="-J" />
<arg value="${outdir-r}" />
<arg value="-M" />
<arg value="AndroidManifest.xml" />
<arg value="-S" />
<arg value="${resource-dir}" />
<arg value="-I" />
<arg value="${android-jar}" />
</exec>
</target>
<!-- Generate java classes from .aidl files. -->
<target name="aidl" depends="dirs">
<apply executable="${aidl}" failonerror="true">
<fileset dir="${srcdir}">
<include name="**/*.aidl"/>
</fileset>
</apply>
</target>
<!-- Compile this project's .java files into .class files. -->
<target name="compile" depends="dirs, resource-src, aidl">
<javac encoding="ascii" target="1.5" debug="true" extdirs=""
srcdir="."
destdir="${outdir-classes}"
bootclasspath="${android-jar}" />
</target>
<!-- Convert this project's .class files into .dex files. -->
<target name="package-dex" depends="dex, package-res">
<echo>Packaging dex...</echo>
<exec executable="${zip}" failonerror="true">
<!--<arg value="-Xmx384M" />-->
<!-- Move Xmx parameter to dx.bat - FIX - BLOCK END -->
<arg value="--dex" />
<arg value="--output=${intermediate-dex}" />
<arg value="--locals=full" />
<arg value="--positions=lines" />
<arg path="${outdir-classes}" />
</exec>
</target>
<!-- Put the project's resources into the output package file. -->
<target name="package-res-and-assets">
<echo>Packaging resources and assets...</echo>
<exec executable="${aapt}" failonerror="true">
<arg value="package" />
<arg value="-f" />
<arg value="-c" />
<arg value="-M" />
<arg value="AndroidManifest.xml" />
<arg value="-S" />
<arg value="${resource-dir}" />
<arg value="-A" />
<arg value="${asset-dir}" />
<arg value="-I" />
<arg value="${android-jar}" />
<arg value="${out-package}" />
</exec>
</target>
<!-- Same as package-res-and-assets, but without "-A ${asset-dir}" -->
<target name="package-res-no-assets">
<echo>Packaging resources...</echo>
<exec executable="${aapt}" failonerror="true">
<arg value="package" />
<arg value="-f" />
<arg value="-c" />
<arg value="-M" />
<arg value="AndroidManifest.xml" />
<arg value="-S" />
<arg value="${resource-dir}" />
<!-- No assets directory -->
<arg value="-I" />
<arg value="${android-jar}" />
<arg value="${out-package}" />
</exec>
</target>
<!-- Invoke the proper target depending on whether or not
an assets directory is present. -->
<!-- TODO: find a nicer way to include the "-A ${asset-dir}" argument
only when the assets dir exists. -->
<target name="package-res">
<available file="${asset-dir}" type="dir"
property="res-target" value="and-assets" />
<property name="res-target" value="no-assets" />
<antcall target="package-res-${res-target}" />
</target>
<!-- Put the project's .class files into the output package file. -->
<target name="package-java" depends="compile, package-res">
<echo>Packaging java...</echo>
<jar destfile="${out-package}"
basedir="${outdir-classes}"
update="true" />
</target>
<!-- Put the project's .dex files into the output package file. -->
<target name="package-dex" depends="dex, package-res">
<echo>Packaging dex...</echo>
<exec executable="${zip}" failonerror="true">
<arg value="-qj" />
<arg value="${out-package}" />
<arg value="${intermediate-dex}" />
</exec>
</target>
<!-- Create the package file for this project from the sources. -->
<target name="package" depends="package-dex" />
</project>
修改build.xml后,你可以再次尝试运行ant。
用ADB安装你的应用
第一步是启动模拟器。在Android /tools文件夹中,找到emulator.exe文件并执行它。这样启动你的Android服务端。也就是说,启动模拟器同时也在你的PC上启动了一个虚拟的手机,如下所示。然后你就可以使用不同的工具与服务端通信,如同安装应用和调用shell环境的做法一样:
要在Android服务端安装命令行应用,你需要使用adb。adb是 通过模拟器启动的Android服务端的连接器。adb包含很多有用的功能,允许你与Android服务端交互;其中之一即允许你安装应用。
表6-1列出并说明了adb支持的命令。
表6-1 adb命名
要将你的应用复制到服务端,打开一个windows命令提示窗口并浏览到build.xml文件所在的目录。Adb的命令语法如下:
adb install <apk path>
如果应用正确地安装到了手机上,你会从命令行得到反馈的包大小,如下所示。
切换到你正运行的Android模拟器,你会看到安装在手机上的应用。
如果运行应用时出错怎么办 我第一次使用新的build.xml文件运行应用时,我在Android模拟器上收到了一个错误。如下插图所示,错误指向了一个缺失类。
这个错误看起来指出一个事实,即我的类,不知何故在HelloWorldCommandLine.apk文件中丢失了。你不需要任何Android SDK命令行工具,就可以很容易地补救这个问题。
实际上,.apk文件就是.zip文件。也就是说,你可以用.zip文件解压工具很容易打开他们,看到他们的内部文件。下面的插图显示了利用winrar解压工具查看HelloWorldCommandLine.apk的内容。
文件中缺失的是classes.dex。这是编译后的Dalvik可执行类。浏览我的Android项目的bin目录,我会看到ANT的确成功得编译并生产了classes.dex文件。该文件落在HelloWorldCommandLine.apk之外。用winrar打开.apk文件,我就可以将classes.dex拖放到HelloWorldCommandLine.apk中。在我的.apk文件添加classes.dex后,我就可以保存并关闭文件。
卸载Action的早期版本
当你在运行的Android服务端添加文件后,你就可以卸载HelloWorldCommandLine的早期版本。在你安装另一个应用之前,你不需要卸载一个应用的前版本。然而,为了更好额的了解如何与Android服务端交互,在继续之前卸载你的早期版本吧。
打开Android模拟器,回到你的命令行提示环境,并运行adb shell 命令,这能在Android服务端打开一个shell环境。如果你成功了,你的命令提示窗口会从>变成#。
现在你的Android服务端有一个打开的shell。你可以在此处运行复杂的功能,但是现在集中在一个上:移除旧的HelloWorldCommandLine.apk文件。
在Android服务端,用户安装的应用保存在/data/app目录中。使用cd,浏览app目录,如下所示:
运行命令ls,列出目录的所有文件。你会看到一个名为HelloWorldCommandLine.apk的文件。这个文件代表你安装的Activity。