Android开发从入门到精通(六)

Android开发从入门到精通(6)第六章?使用命令行工具和Android模拟器?使用命令行工具和Android模拟器?-?第六

Android开发从入门到精通(6)

第六章?使用命令行工具和Android模拟器?

使用命令行工具和Android模拟器?-?第六章(1)

关键技能和概念
●?使用Android?SDK命令行工具?

●?创建一个命令环境

●?用一个壳导航到Android服务

●?在Linux里使用?Android?SDK

????到目前为止,本书包含了一些非常宽的科目关于学习如何运行Android平台。就这一点来说,对于使用Eclipse来创建并运行一个小的Adnroid应用程序,你应该非常的舒服。你创建一个新的项目,编辑main.xml文件和<activity>.java文件,然后编译R.java文件。这些是创建Android应用程序的一些基本技能。

????在本章中,你会通过用命令行应用程序开发来扩展你的这些技能。Android开发没必要必须限定在Eclipse?IDE环境里进行。Android?SDK提供了许多命令行工具,可以在没有图形化的IDE的帮助下,开发完整的应用程序。你会使用这些命令行工具首先在Windows,然后再Linux下来创建,编译和运行Hello?World!应用程序。

利用Windows?CLI创建一个壳活动?-?第六章(2)

?Android?SDK有很多的工具来帮助你创建并编译Android应用程序。这些工具帮助那些不愿意使用,或者没有所支持GUI?IDE系统的用户来工作的。总之,如果你一直在用Eclipse在编程,你仍然需要知道Android?SDK命令行工具和它的功能。

????当你运行Android相关的功能,如创建一个Android项目或者在Android模拟器内运行一个应用程序,你实际上是在呼叫到命令行工具的连接器。无论是从命令行接口或者GUI?IDE运行,这些Android命令行工具是Android?SDK的真正核心。

????在下面的章节中,我演示Android工具的功能。ActivityCreator.bat是一个强有力的工具,被用来为你的程序建立一个活动壳(Activty?Shell)。

运行ActivityCreator.bat?-?第六章(3)

???ActivityCreator.bat文件应当在Android?SDK的…/tools/文件目录下。大多数“前向”命令行工具都放置在工具目录的根目录下。“前向”工具是依次呼叫在工具根目录下更深目录的工具。ActivityCreator.bat是工具根目录下一个示例的工具,它运行时会呼叫另外一个工具。使用vi,Notepad或者一个文本编辑器,打开ActivityCreator.bat。它应当包含下面的代码:

注意

ActivityCreator.bat是定义为Microsoft?Windows版本的Android?SDK。在本章的后面部分,你将会学习ActivityVreator.py。这个是Linux版本的ActivityCreator。

@echo?off?
rem?Copyright?(C)?2007?Google?Inc.?
rem?
rem?Licensed?under?the?Apache?License,?Version?2.0?(the?"License");?
rem?you?may?not?use?this?file?except?in?compliance?with?the?License.?
rem?You?may?obtain?a?copy?of?the?License?at?
rem?
rem?http://www.apache.org/licenses/LICENSE-2.0?
rem?
rem?Unless?required?by?applicable?law?or?agreed?to?in?writing,?software?
rem?distributed?under?the?License?is?distributed?on?an?"AS?IS"?BASIS,?
rem?WITHOUT?WARRANTIES?OR?CONDITIONS?OF?ANY?KIND,?either?express?or?implied.?
rem?See?the?License?for?the?specific?language?governing?permissions?and?
rem?limitations?under?the?License.?
rem?don't?modify?the?caller's?environment?
setlocal?
"%~dp0\lib\activityCreator\activityCreator.exe"?%*

????浏览整个的rem声明(批处理文件注释声明),你会看到在文件的底部有一个实用的代码。ActivityCreator.bat被用来呼叫…/tools/lib/activitycreator/目录里的ActivityCreator.exe。这个ActivityCreator.bat是一个工具的示例,它只是放置在SDK其它工具的前端。

????所以,ActivityCreator.bat(或者ActivityCreator.exe)做了什么?ActivityCreator被用来建立指向在哪里需要开始开发你的应用程序初始文件的开发环境。这个路径结构和在第五章第五章(1)程序:Hello?World!讨论过的结构一致。ActivityCreator.bat?创建?R.java,?AndroidManifest.xml,?和所有你应用程序需要的支持文件。

????让我们现在转到命令行环境并且浏览ActivityCreator。在开始菜单,点击运行,在运行的对话框内输入?CMD或者COMMAND,然后点击确定。

????执行这个命令会启动命令窗口。这个窗口和老版本的DOS操作系统环境相同。命令窗口出现后,在光标>后输入ActivityCreator

提示

Microsoft命令提示符接口没有大小写限制。在缺省情况下,如果你使用了大小写限制的不同的开发环境,本章中显示的屏幕截图会不同。

????运行命令ActivityCreator,实际运行的是ActivityCreator.bat,产生下面的输出:?
Activity?Creator?Script?
Usage:?
activityCreator?[--out?outdir]?[--ide?intellij]?yourpackagename.ActivityName?
Creates?the?structure?of?a?minimal?Android?application.?
The?following?will?be?created:?
-?AndroidManifest.xml:?The?application?manifest?file.?
-?build.xml:?An?Ant?script?to?build/package?the?application.?
-?Res:?The?resource?directory.?
-?Src:?The?source?directory.?
-?src/your/package/name/ActivityName.java?the?Activity?java?class.?packageName?
is?a?fully?qualified?java?Package?in?the?format?<package1>.<package2>...?(With?at?
least?two?components).?
-?Bin:?The?output?folder?for?the?build?script.?
Options:?
--out?<folder>:?specifies?where?to?create?the?files/folders.?
--ide?intellij:?creates?project?files?for?IntelliJ

????这个输出简单的指示了你需要提供更多的信息来运行ActivityCreator。更确切的是,你需要传递给命令一个你需要建造的壳应用程序的位置。

注意

从ActivityCreator输出的命令给了你很多不仅仅是你没有提供足够信息的信息。它给了你一个完整的使用工具创建的文件列表。这个文件列表和第五章第五章(1)程序:Hello?World!看起来相似。虽然build.xml没有直接展示在Eclipse用户目前。

????回到命令窗口并且使用下面的选项运行ActivityCreator(如果你使用Unix/Linux环境编程,ActivityCreator同样接受unix-风格路径参数):

--out?c:\AndroidHelloWorld\android_programmers_guide.HelloWorldCommandLine

--out选项告诉ActivityCreator你想要它输出点东西。这个命令选项使用两个参数,<folder>和<package.activity>。第一行告诉ActivityCreator?在一个不存在的文件夹里创建壳应用程序。c:\AndroidHelloWorld.?

提示

如果你定义的文件夹或者路径不存在,AcitivityCreator将会在过程中自动创建一个。

--out的第二个参数是包装名称和活动名称。根据前面章节的习俗,这个实例在本项目中使用android_programmers_guide作为包装的名字并且HelloWorldCommandLine作为活动的名称。

注意

成功运行ActivityCreator并设置你的初始环境和运行新的Android?Project?wizard是一致的。

NOTE?
the?parameters?needed?to?successfully?run?ActivityCreator?and?set?up?your?initial?
environment?are?the?same?as?those?required?by?the?New?Android?Project?wizard.

????在新命令行选项和参数下运行ActivityCreator。你应当从工具的输出看到下面的内容:(略)。下面的章节涵盖了由ActivityCreator创建的文件,因为和由Eclipse创建的文件有一些不同。

项目结构?-?第六章(4)

???ActivityCreator为你的开发创建了一组文件目录和文件。浏览?c:\AndroidHelloWorld\来看一下它的结构。ActivityCreator创建的结构如下图所示(略)

????因为在Eclipse环境之外工作,你有一个不同的环境。当你在例如Eclipse的IDE内工作时,一些特定的功能在场景之后为你工作。假如你工作时没有任何IDE的帮助,ActivityCreator创建了一个文件来概述编译器如何的工作来创建你的项目。当手动运行ActivityCreator,为你创建build.xml文件。当你使用Eclipse来开始一个Android项目时,这个文件并没有被创建。

????它包含了一个指令组,解释了如果转变你的.java文件到一个功能性的Android项目中。这个build.xml文件告诉编译器它需要怎么做来创建你的应用程序。在这个例子中的编译器是Apache?ANT,一个Java基础的工具,被用来使用构造脚本文件到编译的项目。从??http://ant.apache.org/bindownload.cgi.?下载?ANT。

????一旦你下载并安装了ANT,你必须把它增加的PATH声明中。在Windows环境中,右击“我的电脑”,并且选择“属性”来改变PATH声明。build.xml文件被特地为ANT创建用于编译你的Android应用程序。它应该在你项目的根目录,如上图所示。用文本编辑器打开build.xml并看一下它里面有些什么。

????第一个部分的build.xml包含了可以被用户编辑的代码。这部分是其它部分的开始,因为剩下的部分不应当被修改。?
<?xml?version="1.0"??>?
<project?name="HelloWorldCommandLine"?default="package">?
<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.?-->?
<property?name="outdir"?value="bin"?/>

第一部分的build.xml包含下面属性的值:?
●?Project?name?项目名称?
●?Android?SDK?location?Android?SDK位置?
●?Android?tools?location??Android工具位置?
●?Android?framework?location?Android框架位置?
●?Output?location?输出位置

????如果你需要为项目改变任何的这些参数,你可以在这个文件做。但是在build.xml接下来的参数,你会立即看到通知你的警告,告诉你不应当去编辑剩下部分的值:?
<!--?No?user?servicable?parts?below.?-->?
Following?this?warning?in?build.xml?is?a?list?of?parameters?and?values?that?are?critical?to?the?proper?creation?of?your?project.?This?list?includes?compiler?options,?input?directories,?and?tool?locations.?Take?a?look?at?the?following?output?of?the?core?processing?information?of?build.xml:

注意

当Android建议反对改变下面这些参数时,如果你非常熟悉ANT是如何工作的,你可以修改这些选项来符合你特定的需求。

<!--?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"?/>?
<property?name="dx"?value="${android-tools}/dx"?/>?
<property?name="adb"?value="${android-tools}/adb"?/>?
<property?name="android-jar"?value="${sdk-folder}/android.jar"?/>?
92?Android:?A?Programmer’s?Guide?
<property?name="zip"?value="zip"?/>?
<!--?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">?
<arg?value="-p${android-framework}"?/>?
<arg?value="-I${srcdir}"?/>?
<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.?-->?
Chapter?6:?Using?the?Command-Line?Tools?and?the?Android?Emulator?93?
<target?name="dex"?depends="compile">?
<exec?executable="${dx}"?failonerror="true">?
<arg?value="-JXmx384M"?/>?
<arg?value="--dex"?/>?
<arg?value="--output=${basedir}/${intermediate-dex}"?/>?
<arg?value="--locals=full"?/>?
<arg?value="--positions=lines"?/>?
<arg?path="${basedir}/${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.?
Use?the?zip?command,?available?on?most?unix/Linux/MacOS?systems,?
to?create?the?new?package?(Ant?1.7?has?an?internal?zip?command,?
however?Ant?1.6.5?lacks?it?and?is?still?widely?installed.)?
-->?
<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"?/>?
<!--?Create?the?package?and?install?package?on?the?default?emulator?-->?
<target?name="install"?depends="package">?
<echo>Sending?package?to?default?emulator...</echo>?
<exec?executable="${adb}"?failonerror="true">?
<arg?value="install"?/>?
<arg?value="${out-package}"?/>?
</exec>?
</target>?
</project>

????现在你对于build.xml在人工下,命令行创建的Android项目是如何使用应该有了好的理解,你可以开始来编辑你的项目文件并且创建一个Android活动。第一个你需要看的文件是main.xml。使用Windows资源管理器,在AndroidHelloWorld\res\layout目录下找到main.xml。

在Windows?CLI下创建Hello?World!活动?-?第六章(5)?????

???在本部分中,你会使用Windows命令行接口来编辑项目文件。在上一章中,项目文件是由ActivityCreator.bat创建的。你将不使用Eclipse来编辑这些文件并增加一些代码。

编辑项目文件

????在一个XML编译器或者(如果你没有一个XML编辑器)记事本打开main.xml文件。这样你就可以编辑文件并且删除里面的<TextView/>定义。保存过后的main.xml文件是一个空壳。这样你就得到一个编辑<activity>.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?第六章?(6)

????在编译你的项目之前,必须增加另外一个环境变量到你的PC-JAVA_HOME,可以指向你的JDK。即使它只是个PATH声明,你也必须创建一个新的名为JAVA_HOME的变量。

注意?
JAVA_HOME变量是必须的仅仅是因为你使用命令行环境。如果你只使用Eclipse,你不用增加它。

1、右击“我的电脑”,并选择“属性”。?
2、在系统属性下,选择高级选项并点击环境变量按钮。然后会打开一个环境变量窗口。?
3、点击新建按钮来增加一个变量名为_HOME,它的值应该是你Java?SDK的完整路径。见下图(略)

编译并安装应用程序?第六章(7)

??是时候来做一个真正的测试了。你现在可以编辑你的命令行项目了。要编译项目,使用ANT。一旦项目编译完成,你需要在模拟器中安装它。

用ANT编译项目

如果运行ANT时出错该怎么办??第六章(8)

????在你设置好JAVA_HOME环境变量并且ANT在你的PATH声明之后,你应当可以导航到含有build.xml文件的文件夹,并且只要简单的运行ant命令。在你的项目路径下运行ant。如下:(略)。

???运行ant的结果就是一个.apk文件会直接安装到手机(模拟器)中,总之,Eclipse在模拟器中直接为你安装。而这里你需要使用Andorid?Debug?Bridge(adb)工具来安装应用程序,下一节叙述

如果运行ANT时出错该怎么办?

????当你运行ANT时出错该怎么办呢?不用害怕。因为在写本书时,Android还只是一个刚发布的阶段,有些项目可能需要被纠正,当你使用一项新技术时,总会有一些小的更改会发生。当我第一次试着运行ant并且编译我的项目时,我收到了一个错误,如下图(略)。

????一些问题的研究在谷歌的Android开发者论坛上,一个重写的build.xml纠正了一些提供到ANT的命令。在修改过的主要部分已经被加粗。和原来的那个文件比较一下你会注意到明显的不同。

<??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之后,你可以重新运行

用adb安装你的应用程序?第六章(9)

第一步是启动你的模拟器。在Android/tools文件夹找到emulator.exe文件并且执行它。这样就会启动Android服务器。那就是启动了模拟器同时在你的电脑上启动了一个虚拟的手机。如下图(略)。然后你就可以使用不同的工具来和服务器交互了,和安装应用程序和呼叫一个壳环境一样。要在Android服务器安装你的命令行应用程序,你需要使用adb。adb是你到服务器的连接,同模拟器一同开启。

????adb包含了很多有用的功能允许你和Android服务器交互;其中一个功能可以让你安装应用程序。

表格6-1列出了adb接受的命令描述。

????要复制你的应用程序到服务器,打开一个Windows命令提示符窗口并且导航到build.xml文件所在的路径。对于adb,syntax命令如下:?
adb?install?<apk?path>

如果应用程序正确的安装到手机,你会得到一个命令行关于包装大小的反馈。如下。(略)。

命令

描述

install?<path>

安装应用程序到服务器

pull?<remote?file>?<local?file>

将远程文件拉出服务器

push?<local?file>?<remote?file>

将本地文件推进服务器

shell

在服务器上打开一个壳环境

forward?<local?port>?<remote?port>

从一个端口转递流量到另外一个端口(到或者从服务器上)

start-server

启动服务器

kill-server

停止服务器

ppp?<tty>?<params>

通过USB使用一个ppp连接

devices

列出可用的模拟器

help

列出adb的命令

version

显示adb的版本

表6-1?adb?命令

转到运行的模拟器,你将会看到应用程序安装到手机上。

运行应用程序产生了一个错误怎么办?-?第六章(10)

我第一次在使用新的build.xml文件后,运行这个应用程序时,我在Android模拟器上接受到了一个错误。如下图(略)。错误指出一个丢失的类。

注意

你可能会或者不会遇到同样的错误。关键看本书发行时,哪个版本的Android?SDK是可用的,你应当跟从这里的问题解决步骤,因为在后续的项目中会对你有所帮助。

????这个错误似乎指出了一个事实,那就是在HelloWorldCommandLine.apk文件中丢失了一个类。我可以简单的自己去纠正这个错误而不用任何的Android?SDK命令行工具。

????根据结果,.apk文件就是一个.zip文件。就是说你可以用.zip解压缩文件打开它。下面的插图就是用winrar打开HelloWorldCommandLine.apk文件后的样子。(略)。

????丢失的是classes.dex。这个是我的类的编译过的Dalvik可执行性文件。导航到Android项目下bin文件夹,我可以看到ANT成功的编译并且创建了classes.dex文件。这个文件只是被留在了HelloWorldCommandLine.apk文件之外了。在Winrar打开的HelloWorldCommandLine.apk状态下,我可以把classes.dex文件拖进HelloWorldCommandLine.apk。在classes.dex文件被加入HelloWorldCommandLine.apk后可以保存并关闭文件了。

卸载一个较早的活动?-?第六章(11)

???在你增加文件到运行的服务器之前,你将要卸载前一个版本的HelloWorldCommandLine。在安装另外一个程序之前,卸载前一个版本的程序不是必须要做的事。但是,为了更好的查看如何的与服务器交互,在开始前,还是卸载前一个版本的程序吧。

????保持Android模拟器在开启状态,返回到命令行提示符环境并且允许adb壳命令,它会打开Android服务器的壳环境。如果你成功了,你的命令提示符会从>变成#。现在你在Android服务器中有一个打开的壳。有很多的功能现在可以用,但是现在只关注一个:移除旧的HelloWorldCommandLine.apk文件。

提示

记住,Android是一个操作环境。你在壳中可以使用的是标准的POSIX命令。

????在Android服务器中,用户安装的程序被保留在/data/app路径下。使用cd,导航到app路径,如下图(略)。运行ls命令来列出这个路径下所有的文件。你将看到一个HelloWorldCommandLine.apk文件。这个文件展示了你活动的安装。

????现在你已经在服务器上定位了应用程序,你可以移除它了。使用命令语法?rm?HelloWorldCommandLine.apk?来移除应用程序。下图就是rm命令(略)。如果成功,不会返回任何的信息。随后使用ls命令表明,文件已被移除。

警告

因为技术上你通过壳登入了一个Linux服务器,所有在壳内运行的命令是区分大小写的。

????应用程序移除后,输入exit来退出壳并返回到你的命令提示符。

重新安装并启动应用程序?-?第六章(12)

你现在可以使用adb重新安装应用程序了:

Adb?install?HelloWorldCommandLine.apk?

一旦应用程序被安装回服务器,转到模拟器。从模拟器中启动应用程序。它应当能正常工作,如下图(略)。

????现在我们已经谈论过如何在Windows内创建和编辑文件的过程,让我们看看在Linux上会怎么样。即使你是一个顽固的Windows用户,你可能需要注意下面的章节。我发现了对编程绝对有利的开源工具。

Linux上的Hello?World!?第六章(13)

很多的程序员,特别是对开放源代码软件有兴趣的程序员喜欢使用Linux作为平台。谷歌和开放手机联盟已经为这些程序员准备了Android?SDK。这个SDK实际上是同样的SDK(因为java是移动性的),但是被创建的工具特定的运行在Linux上。当我开始写这本书的时候,我在使用一个老版本的红帽Linux作为我的Linux平台。我下载并安装了Eclipse和Android?SDK。然而,它很快成为可以安全运行Android的Linux的一些限制。因为最低要求,你必须有一个支持libstdc++.so.6的Linux。Android文档列出了Ubuntu?Dapper?Drake?作为一个Linux的测试版本。

????如果你还没有决定使用哪一个版本,你可以放心的使用。不幸的是,当我试图安装最新版本的Ubuntu的时候,我电脑的硬件有个问题。于是我决定移除推荐的并且试着用一些新的东西。

????当我决定放弃红帽,我决定使用Fedora?8。本书的下面部分所使用的Linux版本的例子都是从Fedora?8?而来。不过,它们应当在你选择的软件版本上工作的没有问题。

注意

如果你选择Fedora?8,会有一个叫做Fedora?Eclipse的定制包装。如果你试图为Fedora?Linux安装Android?Plugin?(使用本书早些时候的概述),它会提示一个错误要求plugin?org.eclipse.wst.sse.u。你可以要下面两种方式解决:

下载最新Linux版的Eclipse,或者使用Fedora的自动升级程序,这个可以使Linux版的Fedora?Eclipse成为最新。然后可以在这个Eclipse里使用Android?SDK了。?
配置PATH声明

????第一步就是配置PATH声明。路径就是一个路径清单,当一个命令被执行时,操作系统会在这个路径下寻找该命令。要查看你当前配置的路径,从一个terminal里运行下面的内容:

echo?$PATH?

你会得到像下图(略)一样的一些路径声明。使用输出命令来增加Android到PATH声明中:

export?PATH=$PATH:<android?path>

????在Linux中编辑PATH声明会只是在当前的terminal部分改变PATH声明。要永久的改变你的PATH声明。你必须编辑.bash_profile.使用vi来编辑.bash_profile,如下图所示(略)。

????如你所见,PATH声明清晰可见。使用命令:i来使vi成为插入模式,然后增加Android到PATH中。然后按下ESC按钮,使用命令:w来写文件,然后使用:q来退出。

????Linux版本的Android?SDK与一个Python脚本一起提供,activityCreator.py,这个被用来创建你的初始项目。不管怎么说,我喜欢手动创建路径来确保它在我需要它在的地方。使用mkdir来为你的项目创建一个目录。

????创建好项目目录后,你可以运行activityCreator.py?Python脚本。这个脚本的语法非常接近于Windows.bat文件:?

activityCreator.py?--out?<output?directory>?package.activityName?

????使用activityCreator.py脚本来设置你的项目。看看下图activityCreator.py输出的脚本(略)。

提示

activityCreator.py命令是由sudo前缀。sudo命令被用来模拟其他用户的许可(本例为根目录),如果你没有足够的许可来运行要求的命令。在我安装的Fedora,我的用户帐号没有权利与根目录交互。

????项目建好后,编辑HelloWorldLinux.java文件并增加TextView。你可以用很多中方法在Linux中编辑.java文件。可以再次使用vi,或者你可以使用一个如下图的标准文本编辑器(略)。

????最后,从main.xml中移除定义的TextView。你现在编译你的Linux版本的Hello?World!应用程序有两个小的改变。要编译应用程序,使用ANT(这个在Windows环境一样)。伺服ANT应当被预先安装在你的Linux下,特别是当你使用Fedora?8.如果你没有使用Fedora?8,你需要为伺服ANT下载,安装并设置路径。

????当你运行ant,你应当看到一个如下图的输出(略)。

????最后,你需要启动Android模拟器来安装你的应用程序。保持模拟器开启的状态下,执行下面的命令:

adb?install?HelloWorldLinux.apk?

????这个将安装应用程序到Linux?Android服务器。如果命令运行成功,你应当可以在模拟器运行活动了。下一章,研究如何使用Android?SDK来对图片事件作出反应。

在CLI中创建一个图片基础的Hello?World!?第六章(14)

在本章中使用命令行工具来从第五章中重新创建图片为基础的Hello?World!?当你创建这个项目时,记住下面的事宜:

●?在res文件夹中放置图片。

●?检查创建R.java所需要的带有指向图片的任何工具。

●?使用ANT编译项目。

●?使用adb命令来安装并推动应用程序到你的模拟器中。

问专家:

Q:当为Android编程时,有一种操作系统比其他的更好吗?

A:在使用过一些操作系统之后,我还没有注意到哪一种操作系统带有明显的优势。真的只是个人喜好。但是,经常发生的情况是,你可能会看到更多非官方的工具为了Linux平台而发布。因为Linux和Android是开放源码,更多的开放源码开发者倾向于为另一个开放源码平台创建工具。这个最终会给Android带来比Linux更多的好处。

Q:还有其它的命令可以从adb壳环境运行吗?

A:是的。例如,一个有趣的命令就是服务命令,可以被用来检查一个过程的状态,如:service?check?phone

假定手机正在运行,你应当能得到反馈:

Service?phone:?found

另外使用服务命令的方法是打一个电话。模拟器开启的情况下,输入命令并检查模拟器界面:?
service?call?phone?2?s16?"15555551212"

题外话:终于完成第六章的翻译工作了。