关键技能和概念
l??????? 使用Android SDK命令行工具
l??????? 创建命令环境
l??????? 通过shell导航Android服务端
l??????? 在Linux中使用Android SDK
目前,本书已经涵盖了一些宽泛的主题来让你了解并运行Android平台。现在,你应该使用Eclipse创建和运行小Android应用非常顺手。你创建一个新项目,编辑main.xml文件和<activity>.java文件,并重编译R.java文件。这就是你创建Android应用的基本技能。
本章中,你会通过试验命令行应用开发来扩展和丰富你的技能。Android开发不应该仅限于Eclipse IDE。Android SDK提供了大量的命令行工具,帮你脱离图形化IDE Eclipse开发丰富的应用。你将用这些命令行工具,现在Windows中后在Linux中,创建,编译和运行一个Hello World!应用
在Windows命令行创建Shell Activity
Android SDK发布了很多工具帮助你创建和编译Android 应用。这些工具适当的帮助那些不愿或没条件使用GUI IDE的用户。然而,如果在用Eclectic完成所有Abdominal开发工作,你也应该重视Android SDK命令行工具和它们的功能。
当你运行Android相关功能时,如创建一个Android项目或在Android模拟器中运行一个应用,你实际上是在调用Android命令行工具。无论是从命令行接口还是从一个GUI IDE运行,这些Android命令行工具才是Android SDK的真正核心。
下面一节,我阐明Android工具的功能。ActivityCreator.bat是个创建项目所需的Activity shell的有用工具。
?
运行ActivityCreator.bat
ActivityCreator.bat应该在Android SDK的../tools/目录下。大部分前向命令行工具都处在这个tools目录的根部。“前向”工具是依次调用../tools/中的其它深层目录工具的工具。ActivityCreator.bat是运行时从根目录调用其它工具的例子。使用vi、Notepad、或者任何文本编辑器,打开ActivityCreator.bat;它应该包含下面的代码:
@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用来创建你的开发环境,即创建开发应用所需的初始文件。目录结构和第五章探讨的相同。ActivityCreator.bat创建R.java、AndroidManifest.xml和应用所需的全部支持文件。
现在进入命令行环境,探索ActivityCreator。
从开始菜单,点击Run,在Run对话框中输入CMD或者COMMAND并点击OK。
执行该命令启动如下所示的命令窗口。该窗口就是早期的DOS操作环境。
?
当打开命令窗口,在> 提示后输入ActivityCreator。
.运行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。更具体点说,你需要传入你创建shell应用的目录位置的命令。
回到命令窗口,运行带如下选项的ActivityCreator(如果你在Unix/Linux环境中编程,ActivityCreator也接受Unix风格的路径参数):
--out c:\AndroidHelloWorld\android_programmers_guide.HelloWorldCommandLine
--out项告诉ActivityCreator你想输出内容。
这个命令项带两个参数,<文件>和<package.activity>。上一行的第一部分告诉ActivityCreator在不存在的文件c:\AndroidHelloWorld中创建shell应用。
--out项的第二个参数是包名和活动名。按前一节中的创建规则,本例使用android_programmers_guide 作为项目的包名和 HelloWorldCommandLine作为项目的活动名。
用新的命令行选项和参数运行ActivityCreator。你会看到如下输出:
?
下一节会讲解ActivityCreator创建的文件,因为他们和Eclipse中创建的有所不同。
?
项目结构
ActivityCreator创建了大量供你使用和开发的目录和文件。浏览c:\AndroidHelloWorld目录,研究它的结构。ActivityCreator创建的结构如下所示:
?
因为你是在Eclipse环境外工作,所以你的环境会稍微不同。当你使用IDE工作时,如Eclipse,部分功能是在后台执行。由于你是脱离IDE工作的,所以ActivityCreator创建了一个文件,列出了创建项目时编译器需要做的内容。手动运行时,ActivityCreator为项目创建了build.xml文件。当你用Eclipse创建Android项目时不会创建该文件。它包含了一组指令,即阐明如何将你的.java文件转换成一个功能性Android项目。
build.xml文件告诉编译器如何创建你的应用。本例中的编译器是Apache ANT,一款基于java的利用build脚本文件的工程编译工具。你需要下载ANT编译你的命令行项目。从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第一部分包含了以下属性的值:
???l??????? 项目名称
?? l??????? Android SDK位置
?? l??????? Android tools位置
?? l??????? Android框架位置
?? l??????? 输出位置
如果你需要更改任何参数,你可以在这个文件中完成。然而,紧跟这些参数之后,你会在build.xml中看到一条警告信息,即你不可以更改其余的任何值:
<!-- No user servicable parts below. -->
build.xml的这条警告之后,是一个参数与值的列表,严格保证了项目的正确创建。这个列表包括了编译项,输入目录,工具位置。看一下下面的build.xml核心流程信息的输出结果:
<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" />
<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. -->
<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>