安卓应用开发学习手册-一-

166 阅读1小时+

安卓应用开发学习手册(一)

原文:Learn Android App Development

协议:CC BY-NC-SA 4.0

零、简介

Android 操作系统是当今世界上最受欢迎的操作系统,可以在从手表到高清智能手机、触摸屏平板电脑、电子书阅读器到交互式电视机的所有设备上运行。

由于世界各地的人们拥有数十亿台 Android 消费电子设备,因此,如果你有正确的概念和设计,为这些人开发应用可能是一项非常有利可图的事业。这本书将有助于你学习如何创建一个有吸引力的 Android 应用,它跨越多种类型的 Android 设备并支持多种 Android 操作系统版本。

我写了学习 Android 应用开发作为我的绝对初学者 Android 应用标题的下一个层次,目标读者是那些更精通技术,并且熟悉计算机编程概念和技术的读者。话虽如此,这将是一个很好的后续标题绝对初学者的 Android 应用标题,都涵盖了最新的 Android 4.2.2 果冻豆和 Android 操作系统版本。

我设计这本书是为了比大多数 Android 应用开发书籍更全面地概述 Android 应用开发工作流程。出于这个原因,本书涵盖了各种其他开源软件包的使用,例如 GIMP 和 Audacity,以及它们的使用如何适应整个 Android 应用开发工作流程。这种方法使这本书与目前市场上的其他 Android 应用开发书籍截然不同。

这本书从安装最新的 Java 和 Android SDKs 以及带有 Android ADT 捆绑包的 Eclipse IDE 开始,然后通过创建一个基本的 Android 应用,并在每章中添加到该应用中。我们继续这个过程,直到所有的主要概念都包含在一个全面的 Android 应用中。这种方法与现实世界的应用开发更加相似,在现实世界中,随着时间的推移,应用会不断地被添加,随着时间的推移,应用会变得越来越健壮,功能也越来越丰富,同时确保每个新功能不会导致应用崩溃。

我们将探讨 Java 对象和构造函数、使用 XML 标记的用户界面设计、数字图像和图形设计、数字视频和动画、音频采样和音频排序,以及其他先进的新媒体概念和多媒体应用功能,因为这是当今 Android 应用开发中流行的内容。我们关注 Android 操作系统的核心领域,包括内容供应器(SQLite 数据库)、广播接收器、服务以及使用事件、意图和活动,所有这些都非常详细。

我们涵盖了在 Android 操作系统包含的更高级领域工作所需的基础知识。其中一些包括数字图像合成、数字视频优化、程序动画、数据库设计、多屏分辨率支持、3D 渲染和类似的高级主题,Android 开发人员需要了解这些主题的基本知识,以便在他们的应用设计和开发工作流程中智能地工作。

如果您想要全面了解 Android、Eclipse、Java、XML 和 Android 开发人员工具环境,以及如何在领先的开源新媒体内容设计和开发工具中优化使用这些技术的知识,那么这本书将会引起您的极大兴趣。

一、为 4.2 版本构建 Android IDE:获取、安装和配置 Android 开发环境

在学习 Android 应用开发之前,我们需要做的第一件事是在我们的开发工作站上构建一个可运行的 Android 应用开发环境。希望你有一台入门级的四核 AMD 或 Intel 电脑,配 4GB 或以上 DDR 内存,Windows 7 或 Windows 8;我将为这本书使用的电脑是 398 美元的宏基 64 位四核 AMD,运行频率为 3.1GHz,配有 4GB 的 DDR3 内存和 1TB 的硬盘驱动器,以及我在沃尔玛买的 Windows 7。

幸运的是,对于我们这些 Android 应用开发者来说,只需几百美元就能买到非常强大的 64 位计算机!如果你有一台 32 位的计算机,这也同样适用于 Android 应用开发,因为 Android 4.2 开发环境有 32 位和 64 位两种版本。此外,我们将在本书中用于应用开发的所有软件都是免费的商业用途,也称为开源软件,因此,现在启动自己的 Android 应用软件开发业务的成本确实很低。

如果出于某种原因,你想使用早于 Android 4.2.2 的开发环境(我强烈建议不要使用),本书末尾有一个附录,介绍了安装 Android 4.1.2 开发环境的更复杂的工作过程。

我们的攻击计划

在本章中,我们将确保我们的系统拥有最新版本的 Oracle Java 6 软件开发包 (Java SDK,也称为 JDK,或 Java 开发包)编程环境,以及 Android 软件开发环境,其中包括 Google Android 软件开发包(SDK)、Eclipse 的 Android 开发工具(ADT)插件和 Eclipse 4.2 集成开发环境(IDE)。

所有这些一次性安装在一起的软件被称为 Android ADT 捆绑包 ,从 Android 4.2 开始,你现在可以在http://developer.android.comAndroid 开发者网站一次性下载所有这些软件,下载容量不超过 400MB。

在 Android 4.2 Jelly Bean+(Android API 17 级)之前,开发者必须单独下载并安装这些组件中的每一个,这相当繁琐。如果你想这样做,或者想看看必须这样做是什么样子(并更好地理解 Eclipse 和 Android SDK 和 Android ADT 之间的关系),你可以在本书的附录 A 中看到安装的详细版本。

一旦下载并安装了我们的 JDK,我们将下载并安装一个名为 Android ADT 捆绑包的 Android 集成开发环境(IDE) ,它的基础是 Eclipse 4.2 Juno for Java EE IDE。Eclipse 为我们提供了一个流畅的图形用户界面(GUI ),我们可以用它来编写、运行、测试和调试我们的 Android 应用代码,从而使开发 Android 应用变得更加容易。

Eclipse 运行在 Java Runtime Environment (JRE) 之上,因为 Eclipse 是用 Java 编写的,因此它使用 Java 平台来运行自己的代码库,这些代码库构成了 Eclipse IDE 用户界面和特性集,您将会看到(随着您在本书中的深入)这些特性确实非常广泛。

这是我们首先下载并安装 Java 6 JDK 的主要原因,这样 Java SDK 和 JRE 就在我们的工作站上了。这样,一旦我们开始安装基于 Eclipse 的 ADT 包,Eclipse 就可以很容易地找到 Java 运行时环境(以便 Eclipse 可以启动和运行)。一旦 Eclipse 能够找到 Java,它可以使用 Java SDK 为我们的 Android 开发环境构建 Java 编程代码基础,因为 Android API(SDK)是基于 Java 6 API(SDK)的。

一旦我们下载并安装了 ADT 包,并在 Java 6 上顺利运行,我们实际上已经在一个包中安装了 Google Android 软件开发工具包(SDK)、Eclipse 4.2.2 IDE 和为 Android 4.2.2 API Level 17 开发所需的所有 ADT 插件。

从鸟瞰的角度来看,如果这个过程被公式化为一个方程,它看起来会是这样的:

JDK (Java 6 SDK) + ADT 捆绑包(Eclipse + Android SDK + ADT Eclipse 插件)=自定义 Android IDE

作为 Android Bundle 安装和开发使用配置工作流程的一部分(第二个主要部分),我们将安装一些 Android 虚拟设备 (AVD) 模拟器,这些模拟器将存在于 Eclipse 4.2 中,允许我们在各种 Android 虚拟设备上测试我们的应用,例如虚拟 Nexus 7 平板电脑,虚拟 Nexus S 智能手机,甚至虚拟 GoogleTV 电视机。因此,让我们现在就开始这个过程,这样我们就可以完成它,并在下一章开始开发应用!

Android 编程基础:Java 6

从编程和集成开发环境(IDE)的角度来看,Android 应用开发的基础是 Java 6。Android 应用是使用 Java 6 编程语言编写的(也使用 XML,我们将在第二章中更详细地讨论),Android 应用是在 Eclipse 4.2.2 IDE 中开发的,它也是用 Java 6 编程语言编写的,并且运行在 Java 6 运行时环境(也称为 JRE)之上。委婉地说,您设置构成 Android 开发环境的各种软件组件的确切顺序非常重要,这也是第一章的原因。

因此,我们既有 Java 编程语言(我们可以通过 JDK 或 Java 开发工具包获得)又有 Java 运行时环境(JRE )(它是 JDK 的一部分),请访问 Oracle TechNetwork,下载最新的 JDK 6 安装软件并将其安装在您的计算机上。我们这样做首先是因为 Eclipse 需要 Java 来运行,也就是说,Eclipse 可以说是在 Java 平台和语言的“顶部”运行。Android 的 Android 开发者工具(ADT)插件也需要 Java 和 Eclipse,所以我们首先安装 Java 平台和 Java 环境,然后安装 Android ADT 包。

我们开始吧。

安装 JDK

我们必须做的第一件事是访问 Java SDK 下载页面,有两种方法可以做到这一点;一个是通用的,一个是精确的。即使 Oracle 更改了其 Java SDK 下载页面的位置(它很可能不会更改),也始终有效的通用方法是使用 Google 搜索,关键字短语为**“Java SDK Download”和**,这将显示 Oracle TechNetwork Java 下载 URL。第二种方法是直接在浏览器中键入页面的 URL。下面是网址:

`http://www.oracle.com/technetwork/java/javase/downloads/index.html`

这指向的是 Internet (HTTP)和 Oracle 网站在它们的 TechNetwork 区域(文件夹)在 Java 区域(子文件夹)在 Java SE 或 Standard Edition 区域(子子文件夹)在下载区域(子子子文件夹)。Java 有三个主要版本:面向个人用户的 SE 或标准版,面向大量用户的 ee 或企业版,以及面向老式移动翻盖手机的 ME 或 Micro 版。大多数现代智能手机使用 Android 和 Java SE,而不是 Java ME。Android 非常酷的一点是,它像 PC 一样使用完整的 Java 标准版(即 Java SE)。这是因为 Android 运行在完整版本的 Linux 操作系统内核之上,所以对于所有实际用途来说,Android 消费电子设备本质上是一台成熟的 Linux 计算机。

一旦你输入了这个 URL,你就到达了 Java 6 JDK 下载页面,你需要找到这个页面的 Java 6 JDK 下载部分,它看起来就像图 1-1 中所示的(部分)页面部分。

9781430257462_Fig01-01.jpg

图 1-1。Oracle tech network Java SE 网页的 Java SE 6 JDK 下载部分

向下滚动页面大约一半,点击 JDK 下的蓝色下载按钮(记住,JDK 既包含又包含JDK 和 JRE,所以根本不要下载 JRE),如图图 1-1 所示。

这将带您进入图 1-2 所示的 Java 6 JDK 下载页面,您首先接受软件许可协议,然后下载 Java 6 的 Windows 32 位版本或 Windows 64 位版本。

9781430257462_Fig01-02.jpg

图 1-2。接受 Java 6 许可协议并下载 Windows x86 32 位或 Windows x64 64 位。exe 文件

如果您使用的是 Linux 操作系统或 Solaris 操作系统,也可以在这里找到这些操作系统的 32 位和 64 位版本。请注意,在下载 Windows x86 32 位之前。exe 文件或 64 位 Windows x64。exe 文件,必须点击网页部分顶部“接受许可协议”选项旁边的单选按钮选择器,如图图 1-2 所示。一旦你这样做了,右边的下载链接就会变成粗体,你可以点击它们来下载安装文件。

如果你有 32 位 Windows 操作系统,如 Windows XP,点击jdk-6u43-windows-i586.exe链接(或任何最新的更新版本),或者如果你有 64 位 Windows 操作系统,如 Windows 7 或 Windows 8,点击jdk-6u43-windows-x64.exe链接(或任何最新的更新版本),然后将 JDK 6 安装程序文件下载到你工作站上的下载文件夹中。请注意,你不需要下载这两个文件。

删除任何过期的 JDK

在您安装当前的 Java 6 JDK 之前,您应该检查您的系统,以确保您的工作站上没有预先存在的(旧的)Java 版本。这是在 Windows 中通过控制面板完成的,控制面板可通过 Windows 开始菜单访问。现在启动控制面板,找到标有“程序和功能”的图标,启动如图图 1-3 所示的程序和功能对话框。

9781430257462_Fig01-03.jpg

图 1-3。右键单击现有的 Java 安装,选择卸载将其从系统中移除

注意,在我的工作站上,我已经安装了 32 位 Java 6 Update 31。因为我想在这个安装过程中安装最新的 64 位开发软件,所以我将使用完全相同的工作过程卸载以前的 Java 6 Update 31 安装,以及任何旧版本的 Eclipse 和 Android(如果它们存在,但它们不在这个特定的工作站上)。

为此,你需要选择旧版本的 Java,然后右击它,选择卸载选项,如图图 1-3 所示。然后,Windows 继续从您的系统中删除旧版本的 Java(以及 Eclipse 和 Android,如果需要的话)。

接下来,进入你的下载文件夹(或者你的桌面,或者任何你保存文件下载的地方),双击 jdk-6u43-windows-i586.exe 或者 jdk-6u43-windows-x64.exe文件开始 Java 6 的安装。接受安装的默认设置,如果您有一个配有高速硬盘驱动器和至少 3GB 内存的现代工作站,安装过程应该会很快。

一旦 Java 6 JDK 安装完成,您就可以下载并安装 Android ADT 包了。接下来让我们这样做,这样我们就有了一个 Android IDE 设置,可以在本书的剩余部分中用于我们未来的 Android 应用开发。

Android 开发者工具(ADT)包

从 Android 4.2 Jelly Bean 开始,Android 软件开发工具包(或 Android SDK)与 Eclipse IDE 和 Android 开发工具(ADT) 捆绑在一个称为 ADT Bundle 的 400MB 大下载包中。

下载 Android ADT IDE

我们必须做的第一件事是访问 Android 开发者网页,同样有两种方法可以做到这一点;一个普通,另一个精确。即使谷歌改变其 Android 开发者网页的位置(它很可能不会改变),通用的方法也总是有效的,那就是使用带有关键词短语“Android Developer Website”的谷歌搜索,这应该会调出Developer.Android.com网站 URL。第二种方式是直接在浏览器中输入 Android 开发者网页的网址(建议大家熟记这个网址):http://developer.android.com/index.html

.

一旦你输入网址,你就到达了 Android 开发者网站主页,你需要找到页面底部的Get SDK按钮,它看起来就像图 1-4 所示的菜单。

9781430257462_Fig01-04.jpg

图 1-4。选择获取 SDK 按钮转到Developer.Android.com站点上的 Android SDK 下载页面

一旦你点击获取 SDK 按钮,你就会被带到获取 Android SDK 页面,在这里你会看到一个蓝色的大按钮,上面写着:下载 Windows 的 SDK - ADT 捆绑包(如果你目前使用的是 Linux 或 Macintosh 操作系统,也可能是 Linux 或 Macintosh 网站会自动检测您的操作系统,并为您提供正确的下载链接)。点击这个蓝色按钮,如图 1-5 所示,进入下载页面获取 Android SDK ADT 捆绑安装程序。zip 文件,现在有 32 位和 64 位版本。

9781430257462_Fig01-05.jpg

图 1-5。点击Developer.Android.com获取 Android SDK 页面上的下载 Windows ADT 捆绑包 SDK 按钮

一旦你点击下载 SDK ADT 捆绑包按钮,你将被带到如图图 1-6 所示的页面,在这里你可以阅读软件包的许可协议(Android 4.2.2 SDK,Eclipse 4.2.2,Android 开发者工具等)。)下载到捆绑安装中。

9781430257462_Fig01-06.jpg

图 1-6。同意条款和条件,并在Developer.Android.com页面下载面向 Windows 的 SDK ADT 捆绑包

在您单击**“我已经阅读并同意上述条款和条件”复选框,然后选择您正在运行的操作系统类型(32 位或 64 位)的单选按钮后,您可以单击下载 Windows SDK ADT 捆绑包**按钮,并下载适合您的操作系统类型的 zip 文件。

因为我有一个 Windows 7 64 位四核 AMD 系统,所以我选择了 64 位 SDK 版本,这是截至 Android 4.2 API Level 17 最近才推出的版本,也称为 Jelly Bean Plus。在 2012 年 11 月下旬 Android 4.2 问世之前(在感恩节假期,信不信由你),Android 应用开发人员别无选择,只能使用 32 位开发软件环境,即使他们在 64 位工作站上开发。因此,如果您喜欢在 64 位工作站上保持 64 位的整洁,那么您很幸运!现在,让我们开始下载,将那个 400MB 的文件下载到我们工作站的硬盘上。

安装 Android ADT IDE

400 MB 下载完成后,打开 Windows 资源管理器文件导航和文件管理实用程序,找到。系统下载文件夹中的 zip 文件。如果找不到,请在右上角的搜索框中使用通配符输入 zip 文件的部分名称,并在左侧选择您的计算机或 C:\ drive,Windows 资源管理器将为您找到该文件。

下面是我使用的搜索字符串:adt-bundle*.zip(星号通配符可以扩展以适合文件名中的任何内容)。

一旦您找到了 adt-bundle-windows zip 存档文件,右键单击它以获得一个上下文相关的菜单,其中包含可以对该文件执行的所有操作,并选择 **Extract All。。。**选择将 zip 存档中的所有文件和文件夹提取到您的硬盘上。这显示在图 1-7 (用红色圈出)。

9781430257462_Fig01-07.jpg

图 1-7。右键单击 Downloads 文件夹中的 adt-bundle zip 文件,并选择 Extract All。。。选择权

接下来,您将看到一个提取压缩文件夹对话框,要求您选择要将 ADT 包文件和文件夹层次结构提取到的目标目录。如图 1-8 中的顶部对话框所示,存档提取实用程序将文件的当前位置放入您的系统下载文件夹作为其目标路径,这并不奇怪,因为它确实不知道您想要将这些文件放在哪里,所以它做了一个假设,将自己放在 zip 文件当前“站立”的地方,可以这么说。让我们改变位置,将文件放在工作站上更合理的位置。

9781430257462_Fig01-08.jpg

图 1-8。将解压缩文件的目标文件夹从 C:\Users\Username\Downloads 更改为 C:\adt-bundle-windows

因为我们并不真正希望我们的 adt 包安装到我们的 downloads 文件夹中(我们主要使用它来保存我们的文件下载),所以最简单的工作过程是将它移动到我们的 C:\ primary 硬盘驱动器的顶部或“根目录”,所以让我们在文件名中单击 ADT 包前面的光标,然后在自动生成的路径名的 Downloads、( Your User Name Here )和 Users 部分上退格。

这样,您就在刚刚下载的作为文件夹名称的adt-bundle-windows-x86 .zip文件名前面加上了 C:\ hard drive 说明符。这将把 ADT 包安装在主硬盘分区上 C:\驱动器的根目录(顶部),您可以在需要的任何时候方便地看到和找到它。产生的路径显示在图 1-8 中屏幕截图的下部。

注意,如果你愿意,你也可以删除文件夹名称的windowsx86部分,并把文件夹命名为C:\ADTC:\ADT-Bundle,或者C:\Android_Development_Environment或类似的名字。因为您将找到并设置此应用可执行文件的快速启动图标,所以无论您将此顶级文件夹称为什么都不重要,只要您可以轻松找到它。

一旦你点击提取按钮,你会得到一个小的进度对话框,如图图 1-9 所示,它向你显示了所有的 8740 个项目(584 兆字节)正在被膨胀并复制到你的硬盘上。这个过程完成后,打开您的 Windows Explorer 文件查看实用程序,找到 eclipse.exe**,**,这是 Eclipse 4.2.2 应用的可执行文件。

9781430257462_Fig01-09.jpg

图 1-9。从 400MB 的 ADT 捆绑包 zip 文件中提取 8,740 个文件,共 584MB

为此,在 Windows Explorer 实用程序中打开左侧导航面板上的 C: drive,然后查找您下载、安装并命名的 adt-bundle-windows-x86 文件名,在该文件名下,您将找到 eclipse 文件夹及其子文件夹,如图图 1-10 所示。如果您使用了自己的自定义名称,比如ADT_Bundle,那么就寻找您决定用于 ADT 包文件夹的名称。

9781430257462_Fig01-10.jpg

图 1-10。在 Windows 资源管理器中找到 Eclipse 应用文件,点击右键调用“锁定到任务栏”特性

在任务栏上设置快速启动图标

在单词 eclipse 旁边寻找一个紫色球体,其文件类型为“application ”,这就是您的 Eclipse IDE 软件可执行文件。接下来,右键单击这个 Eclipse 应用文件以获得另一个上下文相关的命令菜单,然后选择该菜单第三部分中的固定到任务栏命令。这将 Eclipse 作为一个快速启动图标安装在任务栏程序启动区域。这个工作过程也如图 1-10 中所示。

一旦从右键菜单中选择了 Pin to Taskbar 命令,Eclipse 4.2 ADT Bundle 紫色球体启动图标就会出现在 Windows 任务栏上。这通常位于操作系统屏幕的底部,但可以停靠(通过拖动)到屏幕的顶部,甚至是左侧或右侧。图 1-11 显示了安装在我的 Win7 任务栏上的 Eclipse 4.2 ADT 捆绑包启动图标以及其他专业开源软件包(GIMP、Blender 3D、Audacity、Lightworks、OpenOffice 和 Chrome,按此顺序显示),其中许多我们将在本章稍后安装。

9781430257462_Fig01-11.jpg

图 1-11。Eclipse 4.2 ADT 捆绑包启动图标显示在 Windows 任务栏的最左侧

单击 Eclipse 快速启动图标,确保 Eclipse for ADT 启动;如果是的话,这意味着您已经正确地安装了 Java 6,并且 Eclipse ADT Bundle 已经成功地找到了 Java,并且正在使用它来运行它的集成开发环境。启动屏幕如图 1-12 所示。

9781430257462_Fig01-12.jpg

图 1-12。通过新安装的快速启动图标启动 Eclipse 4.2.2 的 Android 开发者工具版本

值得注意的是,从 Android 4.2 Jelly Bean+开始,Eclipse Juno 4.2 启动屏幕现在已经消失,新的 ADT Bundle 启动屏幕显示 Eclipse 现在是我们刚刚安装的 64 位 Android Developer Tools 软件包的一个集成部分。

启动和配置 Android 开发人员工具 IDE

在您启动 Eclipse 4.2 for Android Developer Tools 软件后,您看到弹出的第一个屏幕是Contribute Usage Statistics对话框。您只在第一次启动 Eclipse ADT 包时看到这个屏幕,所以现在选择您想要的共享使用统计信息的选项。如果你愿意,你可以随时通过 Android image的使用统计菜单序列改变你的想法(选择的选项)。

我选择了将使用统计数据发送给 Google (是)选项,这样 Google 就可以看到我是如何使用 Eclipse 和 ADT 的,这样他们就可以对产品进行改进。您也可以选择没有负面影响的“否”选项。该对话框如图图 1-13 所示。

9781430257462_Fig01-13.jpg

图 1-13。首次启动 Eclipse ADT 软件时遇到的 Contribute 使用统计对话框

做出选择后,单击 Finish 按钮,Eclipse ADT 包继续启动 Android 集成开发环境(IDE)。

当你第一次启动 Eclipse 4.2 的 Android 开发者工具版本时,你会看到一个 Android IDE 欢迎界面。我们将在本书的前几章中介绍屏幕上的所有内容,所以如果你想读的话,请全部阅读,然后使用顶部 Android IDE 标签右侧的 X 关闭它。一旦你这样做了,一个空版本的 Eclipse IDE 就会出现,如图 1-14 所示。

9781430257462_Fig01-14.jpg

图 1-14。 Eclipse 4.2 for ADT 首次启动时显示空的包资源管理器、编辑、控制台和大纲窗格

我们要做的第一件事是确保我们刚刚安装的 ADT 包是最新的。我们通过帮助菜单和位于底部的检查更新命令来完成。一旦你选择了这个选项,你会看到如图图 1-15 所示的对话框。如果在 ADT 软件包安装过程中安装了 8,740 个文件的更新版本,您将看到**检查更新。。。**函数“获取”它们,并更新当前系统上的旧版本。

9781430257462_Fig01-15.jpg

图 1-15。使用 Eclipse 和 Google 上的软件库在线检查 Android 软件更新

现在让我们看看如何在任何时候访问 Eclipse ADT 捆绑包的 Android SDK 部分,以了解 Eclipse 中当前安装的 Android API 支持级别。

Android SDK 管理器工具

因为我们下载了 Android 4.2 ADT 捆绑包,所以我们知道这将至少是 Android 4.2 API Level 17,但现在让我们使用 Android SDK Manager 工具来深入了解一下,看看 Android SDK 实际上为我们提供了哪些支持。我们可以通过 Eclipse 4.2 的窗口菜单,以及位于该菜单底部的 Android SDK 管理器选项,随时访问 Android IDE 的 Android SDK 部分。点击这个选项会打开一个 Android SDK 管理器窗口,显示我们当前在 Android IDE 中安装了哪些 API 级别(Android OS 版本)。让我们现在就开始,这样您就可以看到 ADT 捆绑包实际安装在您的 PC 上。

正如您在图 1-16 中看到的,这包括 Android SDK 工具、Android SDK 平台工具、Android SDK 4.2 平台、ARM 处理器系统映像(用于在我们即将设置的仿真器中进行测试)以及 Android 支持库。 Android 支持库允许支持以前版本的 Android,因此我们不需要下载所有其他 API 级别来支持所有的硬件设备。值得注意的是,这是我们在本书的示例中只使用在此过程中安装的 Android API Level 17,而不下载 Android SDK Manager 中显示的任何其他 Android API 的主要原因。

9781430257462_Fig01-16.jpg

图 1-16。 Android SDK 管理器对话框,显示 ADT 捆绑包中安装的库和包

将来,如果你绝对需要开发其他版本的 Android,比如亚马逊 Kindle Fire 的 2.3.7,或者亚马逊 Kindle Fire HD 的 4.0.4,只需选择这些 Android 版本,然后点击安装包。。。窗口右下角的按钮。我强烈建议你一次只开发一个 API 级别,并且只针对那些你完全确定需要开发的 Android API 级别,因为每个级别都需要下载数百兆字节的文件和文档。

因为我们现在不会对 Android SDK 管理器做任何事情,所以单击窗口右上角的红色 X 关闭它,让我们准备好为我们正在开发的 Android 设备设置模拟器。在下一节中,我们将学习如何为一些更流行的智能手机、平板电脑和 GoogleTV 消费电子设备设置 AVD 仿真器。

配置 Android 虚拟设备(avd)

为本书的其余部分准备好您的 Android 开发环境的过程的最后一步是设置您的 Android 虚拟设备 (AVDs)。一个 AVD 是一个模拟器,它模仿安卓智能手机、平板电脑、电子阅读器、独立电视(GoogleTV)或机顶盒消费电子产品,允许你在你的工作站上测试你的安卓应用。

拥有一个仿真器是很有必要的,因为不断地将应用上传到实际的物理 Android 设备(硬件)上的工作过程比右键单击项目并选择 Run As Android Application 要繁琐得多。这并不是说你不应该偶尔在真正的 Android 硬件设备上测试你的应用,而是 AVD 允许你在开发时测试,并且速度更快,频率更高。在本节中,我们将创建三个这样的设备:一个 Nexus 7 平板电脑、一个 Nexus S 智能手机和一个 Android iTV 电视机。

因为你已经在 Eclipse 中,进入窗口菜单,选择底部附近的 Android 虚拟设备管理器选项。这将打开 Android 虚拟设备管理器对话框,其中列出了你的 avd。您当前没有 AVDs 设置,它显示:在对话框的中心区域没有可用的 AVD,如图图 1-17 所示。

9781430257462_Fig01-17.jpg

图 1-17。 Android 虚拟设备管理器对话框——点击新建。。。添加 AVD 的按钮

要向您的 Eclipse 环境添加一个新的 AVD,单击 New。。。对话框右上方的按钮,打开创建新的 Android 虚拟设备(AVD) 对话框。

创建您的 Nexus 7 平板电脑模拟器

我们要做的第一件事是命名我们的仿真器,所以在**名称:字段输入:Android _ 4.2 _ Emulator _ Nexus _ 7,如图图 1-18 所示。在设备:字段中,使用下拉菜单(通过向下箭头)选择 Nexus 7 平板电脑选项。然后选择目标:**对于仿真器,是仿真器的 API 级别,是 Android 4.2,或者 API 级别 17,是 Android OS 目前最新的修订版。

9781430257462_Fig01-18.jpg

图 1-18。使用 AVD 管理器为 Nexus 7 平板电脑和 Nexus S 智能手机创建新的 Android 设备(AVD)

因为 Nexus 7 使用的是 ARM (armeabi-v7a)处理器,所以这个字段是自动为你设置的,不能更改。接下来,检查硬件键盘存在显示带有硬件控件的皮肤,因为这些选项适合拥有无线键盘的用户使用 Nexus 7,大多数严肃的用户都会这样做。

前置摄像头选项下拉菜单设置为:网络摄像头如果您的工作站上安装了网络摄像头,否则选择。这是从 Android 4.2 开始的新的 Android AVD 模拟器功能。注意,在 Android API Level 17 之前,Android Emulator (AVD)不支持任何种类的摄像头测试。

Nexus 7 AVD 配置文件根据 Nexus 7 制造商的硬件规格,为您设置内存选项内部存储设置。接下来,将 SD 卡设置为普通 2048MB SD 卡配置,勾选快照选项。

最后,点击 OK 按钮,创建三个 Android 4.2 AVD 仿真器中的第一个,这一个用于 Nexus 7 平板电脑。如果你打算开发其他一些流行的 API 级别的平板电脑,利用完全相同的工作流程,并添加其他名为 Kindle Fire (使用 Android 2.3.7 API 级别 10 和 HDPI)或 Kindle Fire HD (使用 Android 4.0.4 API 级别 15 和 XXHDPI)的仿真器,例如,如果你需要测试你的应用在那些其他特定硬件平台上的交付。

接下来,让我们为 Nexus S 创建一个智能手机仿真器,如图 1-18 右侧所示,这样我们就有了一个智能手机仿真器和一个平板电脑仿真器。

创建您的 Nexus 智能手机模拟器

我们做的第一件事是命名模拟器,因此在名称字段中输入Android _ 4.2 _ Emulator _ Nexus _ S。在设备区域,使用下拉菜单(通过向下箭头)选择 Nexus S 选项。然后为模拟器选择目标,同样是 Android 4.2 API Level 17。

接下来检查硬件键盘存在显示带有硬件控件的皮肤,因为这些选项适合 Nexus 的高级用户,并使应用测试更容易。如果您的工作站上有网络摄像头,请将前置摄像头选项下拉菜单设置为网络摄像头,否则选择

Nexus S AVD 配置文件根据 Nexus S 的硬件规格为您设置了内存选项内部存储设置。接下来,将 SD 卡设置为普通 1024MB SD 卡配置,勾选快照选项。最后,单击 OK 按钮创建第二个 AVD 仿真器。我们现在在 Android 虚拟设备管理器窗口中创建了两个模拟器,如图 1-19 所示。

9781430257462_Fig01-19.jpg

图 1-19。 Android 虚拟设备管理器展示了两款适用于 Nexus 7 平板电脑和 Nexus S 智能手机的新模拟器

我们真正应该创建来测试我们在本书中的内容的唯一其他类型的 Android 虚拟设备是上市的最新类型的 Android 设备 iTV,或交互式电视机。

为 GoogleTV 支持创建您的 Android iTV 模拟器

Android iTV 电视机运行一个名为 GoogleTV 的品牌版本的 Android 操作系统,可以作为 iTV 电视机、机顶盒(STB)或家庭媒体中心(HMC)使用,甚至可以作为飞利浦产品的 USB 记忆棒使用。

幸运的是,我刚刚得到了新的飞利浦谷歌电视 u 盘产品,用于我的一个客户的 Android 应用开发项目。因此,我有了产品的规格,我需要创建自己的自定义 AVD 设备定义规格来创建用于测试的 AVD。

我需要做的第一件事是查看它是否在标有设备定义的右侧选项卡上的预配置 avd 列表中,如图 1-20 所示。但是,Philips GoogleTVu 盘不在其中,因此我们需要进入另一系列对话框,将 Philips Google TV 产品添加到当前 AVD 管理器设备定义对话框中的产品列表中。我在我们的平板电脑和智能手机模拟器中添加 iTV 模拟器的原因之一是专门向您展示这个工作过程,因为它在 AVD 管理器中比 AVD 创建过程隐藏得更深。

9781430257462_Fig01-20.jpg

图 1-20。AVD 管理器设备定义选项卡,您可以从中选择预定义的 AVD 设备或创建自己的设备

解开这个新设备定义工作流程的关键是,你猜对了,新设备。。。按钮,位于 Android 虚拟设备管理器的设备定义标签面板的右上角。点击新建设备。。。按钮,得到创建新设备对话框,如图图 1-21 所示。

9781430257462_Fig01-21.jpg

图 1-21。AVD 管理器窗口的设备定义选项卡中的创建新设备对话框

“创建新设备”对话框允许我们为 Android 虚拟设备管理器窗口中的“设备定义”选项卡创建自定义产品设备定义。现在让我们为飞利浦谷歌电视 u 盘创建一个。在名称:栏,放置飞利浦的 GoogleTV 盘的产品名称,同时输入最常见的屏幕尺寸: 42 英寸的,其物理像素分辨率为 HDTV 1920 x 1080 像素。因为高清电视没有传感器,不要勾选这四个选项,因为谷歌电视 u 盘没有任何摄像头,也不要勾选这两个选项。飞利浦 GoogleTV 盘产品使用鼠标,因此选择轨迹球的输入部分选项。

该产品具有 1GB 的 RAM,因此在 RAM: 字段中输入一个 1 ,并选择 GiB 下拉菜单选项。该产品具有超大尺寸,因此为尺寸:选项选择 xlarge 值,为屏幕比例:选项选择 long ,因为高清电视是宽屏设备。像素密度为 1920 x 1080 像素,与屏幕尺寸无关,因此选择 XXHDPI 作为密度:设置。由于本产品是 u 盘,选择按钮的软件**:选项,然后启用纵向横向**模式复选框,如图图 1-21 所示,因为本产品在这两种模式下都能正常工作。

正确输入所有这些新产品规格后,可以点击对话框底部的创建设备按钮,将新的产品定义添加到 AVD 管理器窗口的设备定义选项卡中,如图图 1-22 所示。

9781430257462_Fig01-22.jpg

图 1-22。飞利浦谷歌电视 u 盘添加到 AVD 管理器设备定义列表

现在我们在设备定义选项卡中有了 Philips GoogleTV USB stick 产品,我们可以选择它,如图 1-22 所示,并通过单击对话框中间的创建 AVD…按钮,使用该产品定义创建一个新的 Android 虚拟设备仿真器。

这将打开创建新的 Android 虚拟设备(AVD) 对话框,如图图 1-23 所示,在对话框的相关区域有适当的设备设置,很像我们为谷歌 Nexus 产品创建 AVD 仿真器时观察到的情况,如图图 1-18 所示。

9781430257462_Fig01-23.jpg

图 1-23。为飞利浦谷歌电视 u 盘创建新的 Android 虚拟设备

请注意,ADT 为我们将设备命名为AVD _ for _ Philips _ Google TV _ USB _ Stick,并且它还在第二个**设备:**下拉菜单中为我们选择了该产品。目标:默认 Android 4.2 API Level 17 也是自动为我们设置的,所以我们所要做的就是填写内部存储SD 卡值,它们都是 4GB

选择快照选项,确保键盘皮肤选项未选中,因为产品没有键盘或硬件控制功能。注意,我们的内存(RAM)设置是正确的,为 1024 兆字节(1GB),就像我们之前在创建新设备对话框中设置的一样。

填写完所有相关字段后,点击 OK ,为飞利浦谷歌电视 u 盘创建 AVD。请注意,飞利浦谷歌电视 u 盘 AVD 已被添加到图 1-24 中的 AVD 管理器主窗口,我们现在有了用于智能手机、平板电脑和 iTV 的 AVD。

9781430257462_Fig01-24.jpg

图 1-24。飞利浦谷歌电视 u 盘被添加为 Android 虚拟设备

现在我们已经为 Android 应用开发做好了准备,让我们去寻找一些我们将在本书中使用的新媒体工具,为我们的应用添加元素,使它们与众不同。我们将获得主要的新媒体开发软件类型,包括数字图像(GIMP)、数字音频(Audacity)、数字视频(Lightworks)和 3D (Blender)。所有这些专业级开源软件包都可以在所有 Windows (XP、Vista、7 和 8)和 Linux 平台上使用。

Android 开发中使用的新媒体工具

因为我们正在下载和安装第一章中的软件包,以完成开发所必需的所有必要的繁重工作,但这并没有教会我们任何实际的 Android 应用开发,所以让我们也抓住所有其他强大的开源软件,我们将需要与 Android 开发环境结合使用,以创建真正令人难忘的、丰富的媒体加载用户界面(ui)和用户体验(UXs)。

我们将在第一章中解决所有这些软件下载和安装的问题,并为我们自己构建一个内容开发工作站,为所有类型的新媒体内容开发提供良好的服务。

数字成像软件:GIMP 2.8.4

首先,让我们安装领先的开源数字成像软件包 GIMP 2.8.4 for Windows。如果你有 Photoshop CS6 那很好,但是为了确保所有的读者都有一个专业的图像应用,你需要下载并安装 GIMP,因为它是免费的!

你可以找到瘸子 GIMP.org。在页面的右上方,你会看到一个下载按钮以及一个下载链接(见图 1-25 ),点击后会将你带到 GIMP 2.8 下载页面。接下来,单击与您的系统当前运行的操作系统相匹配的 GIMP 程序版本的下载链接。对于我的 Windows 7 工作站,我下载了。GIMP 2.8.4 的 Windows XP、Vista、Windows 7 和 Windows 8 版本的 EXE 安装程序。

9781430257462_Fig01-25.jpg

图 1-25。GIMP 2.8 下载按钮和下载链接位于 www.gimp.org[网站](www.gimp.org)

找到。EXE 安装程序文件,双击它,使用建议的默认设置安装软件。然后,在你的 Program Files 文件夹中找到这个文件,右击应用 EXE 文件,然后固定到任务栏,这样它就位于任务栏的启动图标区域,如前面的图 1-10 所示。您现在离创建一个极其强大的新媒体 Android 应用开发工作站又近了一步。接下来让我们得到一个领先的数字音频编辑软件包。

数字音频软件:Audacity 2.0.3

接下来,让我们安装领先的开源数字音频软件包 Audacity 2.0.3 for Windows。如果你有 Reason、SoundForge 或 ProTools,那很好,但为了确保我们都有一个专业的音频工程应用,你需要下载并安装 Audacity 2.0.3,因为它也是免费的!你可以在 SourceForge.net 开源网站找到 Audacity。

在首页的搜索栏中输入 Audacity ,就会找到【Audacity.SourceForge.Net】的软件下载页面,如图 1-26 所示。在页面的左上角,你会看到一个下载按钮,带你去下载软件,在我的例子中,是 Windows 操作系统版本。

9781430257462_Fig01-26.jpg

图 1-26。SourceForge 的 Audacity 2.0.3 项目。net—单击 Windows 2000/XP/Vista/Windows 7/Windows 8 的下载链接

接下来,单击与您的系统操作系统相匹配的程序版本的下载链接。Windows 版本的 EXE 安装程序。找到。EXE 安装程序文件,双击它并使用默认设置安装该软件。

接下来,在它的 Program Files 文件夹中找到该文件,右键单击该应用 EXE 文件并将固定到任务栏,使其位于任务栏的启动图标区域,如前面的图 1-10 所示。现在,您离创建超级强大的新媒体 Android 应用开发工作站又近了一步。

数字视频软件:EditShare Lightworks 11

接下来,让我们安装领先的开源数字视频编辑软件包EditShare light works 11for Windows。如果你有 FinalCut 或 AfterEffects CS6,那很好,但为了确保我们所有人都有一个专业的视频编辑应用,你应该下载并安装 Lightworks,因为它是免费的!你会在 www.LWKS.com 找到 Lightworks 11,在页面右上方会看到一个下载按钮,带你进入图 1-27 所示的下载页面。

9781430257462_Fig01-27.jpg

图 1-27。用于 Windows installer 的 EditShare Lightworks 11 下载页面

要下载此免费软件,您必须登录或注册,然后您可以单击与您系统的操作系统和位级别相匹配的 Lightworks 程序版本的下载链接。

就我而言,我下载了。Windows 7 64 位版本的 EXE 安装程序,大概 100MB 左右。请务必下载发行说明和自述文件,并彻底阅读它们,因为这是一个高端软件包,过去要花费数千美元。

下载完成后,找到。EXE 安装程序文件,然后双击它,并使用其默认设置安装该软件。如果您只安装一个 light works“seat”(一台机器上的一个副本),请将其设置为数字 1(在安装期间出现的第一个对话框中输入 1 或 001)。请注意,您可能需要在第一个对话框中退格并实际键入一个 1 来激活下一步按钮(使其不变暗并可点击)。

然后,在它的 Program Files 文件夹中找到该文件,右键单击应用 EXE 文件并固定到任务栏,这样它就位于任务栏的启动图标区域,如前面的图 1-10 所示。您现在离创建您一直梦想的强大的新媒体 Android 应用开发工作站又近了一步。

3D 建模和动画软件:Blender 3D

最后,让我们安装领先的开源 3D 建模、渲染和动画软件包 Blender 3D 2.66 for Windows。如果你有 Lightwave 或 Maya,那很好,但为了确保我们所有人都有一个专业的 3D 应用,你应该下载并安装 Blender 3D,因为你又猜对了——它是免费的!

你可以在 www.Blender.org 找到 Blender 3D,在 Blender 主页的左上方,你会看到一个下载菜单,或者,如果你喜欢,在右上方有一个下载 Blender 链接,会带你到下载页面(见图 1-28 )。

9781430257462_Fig01-28.jpg

图 1-28。位于 Blender.Org 的 Blender 3D 网站显示了下载菜单(顶部)和下载 Blender 链接(右侧)

首先,点击下载 Blender 链接,在下载页面寻找与你的系统的操作系统和位级相匹配的程序版本。就我而言,我下载了。Windows 64 位版本的。一旦安装文件下载完毕,找到搅拌机。EXE 安装程序文件,双击它,并使用默认设置安装该软件。

接下来,继续通常的工作过程,在程序文件文件夹中找到该文件,右键单击应用 EXE 文件并固定到任务栏,这样它就位于任务栏的启动图标区域,如之前的图 1-10 所示。

现在,您已经创建了一个全面的新媒体 Android 应用开发工作站,可以在本书以及未来的软件开发项目中使用。这个新的媒体开发工作站将允许您开发具有高级 3D 图像、数字音频、数字视频和数字图像的高度专业的 Android 应用。恭喜你!你刚刚安装了开源软件,如果你付费的话,它的价格将是你刚刚购买这本书的一百倍。不错的投资回报!

摘要

在第一章中,我们准备好了所有的东西(或者更好的是,我们准备好了所有的软糖),为我们将在本书剩余章节中进行的 Android 应用开发做准备。

我们收购并下载了一系列非常有价值的内容制作软件,从 Java 到 Eclipse 到 Android,以及所有主要的四种新媒体类型的领先新媒体应用:3D 建模、数字视频编辑、数字音频编辑和数字图像编辑。

我们学习了 Eclipse 如何在 Java 之上运行,以及 Android SDK 如何通过 ADT 工具插件集成到 Eclipse IDE 中,以创建无缝的 Android 开发环境。我们看到,从 Android 4.2 开始,ADT 捆绑包的安装比过去要容易得多,附录 A 证实了这一点,并在更深层次上展示了 Eclipse 4.2、Android 4.1 SDK 和所有 ADT 插件是如何无缝集成在一起的。

在第二章中,我们将进入正题,创建我们的第一个 Hello World 应用,看看 Android 如何使用 Java 和 XML 以及我们的新媒体资源设置一切。我们将学习 Android 用来描述 Android 应用的不同领域和功能的术语,甚至在本章稍后构建的 Hello World 应用中使用其中的一个。

二、探索 Android 应用开发:Android 的行话并构建您的第一个 Hello World 应用!

因为本书面向已经熟悉计算机编程原理和工作流程的读者,所以每个人都熟悉 Hello World 编程示例的通用概念,该示例用于向我们展示关于任何给定编程语言和平台如何建立其基本代码结构并运行的所有基础知识。

因为我想让我们的读者在本书中尽可能快地达到中级水平,所以在本章的第二部分,我将在这里安装并运行 Hello World 应用。首先,我将讨论 Android 应用开发中使用的术语。然后,我们将使用 Hello World 应用示例向您展示 Android 如何构建其编程环境,并向您展示基本的 Android 应用开发工作流程。

我们将了解如何在 Eclipse 中创建新的 Android 应用项目,如何在 Eclipse Package Explorer 中构建和组织该项目,Android 如何使用 XML 标记快速轻松地定义数据结构、项目参数、操作系统权限和用户界面,这样我们就不必用 Java 来完成这些工作,我们的新媒体素材如何命名并存储在预定义的逻辑资源文件夹层次结构中,当然,Java 编程语言如何通过 Android 包、类、方法和常量来引导和整合这些内容。Android 开发绝对是独一无二的。

然而,首先,我们需要花一点时间预先了解 Android 应用的各种组件。我们将了解 Android 环境中各种 Android 组件的术语。Android 使用一些非常独特的术语或行话来描述各种 Android 应用组件,我们将学习这些行话以及这些组件如何无缝地一起工作。

然后,在本章的下一部分,我们可以开始工作,使用一些新的术语、XML 标记和 Java 编程语言来构建我们的第一个 Android 应用。

Android 应用开发行话

Android 使用非常独特的术语来描述其应用开发的各种组件或领域。在这一节中,我定义了这些领域是什么,以及它们与其他常见编程语言(如 C++ 或 Java)的最接近之处。此外,我将向您提供更多关于除了 Java 和 XML 之外还有哪些开源技术驱动 Android 的见解,以及 Android 如何将其 Java 优化为二进制文件,以便在嵌入式(便携式消费电子)设备上使用。

Android 的基础:Linux 2.6 内核

Android OS 的基础是 Linux 2.6 内核;就像 Eclipse IDE 运行在 Java 之上一样,Android 运行在最新 Linux 操作系统的完整版本之上。所以,是的,任何和所有的 Android 设备本质上都是功能齐全的 Linux 计算机,这就是为什么你现在看到的 Android 设备都有双核、四核和八核处理器,就像“真正的”计算机一样。内存也是如此——大多数 Android 设备都至少有 1GB 的 RAM(随机存取内存),许多设备都有 2GB,很快你就会看到 3GB 或 4GB RAM 的 Android 设备。

Android 操作系统使用 Linux 操作系统的核心库来完成所有使用任何计算机操作系统完成的文件、内存和处理的底层工作,由于 Linux 高度优化,它可以比其他操作系统使用更少的内存(更高效地)来完成这些工作。为什么新的 Windows 8 操作系统的内存效率突然变得如此之高?因为它要和 Linux (Android)竞争,这就是原因。

据传,谷歌在更新的 Linux 3.8 内核上运行 Android 4.2.2,而 Android 5.0 将在 2013 年晚些时候在更现代的 Linux 内核上运行。

Android 优化:Dalvik 虚拟机(DVM)

Android 应用开发者使用 Android SDK 及其 Java 编程语言来访问较低级的 OS 功能,以及 Android 为使用各种新媒体素材、SQLite 数据库和 Android 设备的硬件特征(例如相机、陀螺仪、GPS 等)而提供的其他较高级的功能。

当您编译 Java 代码和其他素材(XML、音频、图像等)时。)Android 使用 DVM 或 Dalvik 虚拟机技术将这些文件优化为高度优化的二进制格式,就像可执行文件一样,只是为了在更小、更便携的设备上运行而进行了更多优化。如果你查看你的 Android APK 文件,你会在你的项目根目录下看到一个. DEX 文件。这是一个 Dalvik 可执行文件。

DVM 不是 Android 开发人员在日常开发中需要关心的事情,我在这里只是提到它,这样如果有一天你碰巧在 Android 相关的 Google 搜索中遇到它,你就会知道它是什么以及 DVM 在整个开发过程中做什么。接下来,让我们进入 Android 的行话,了解 Android 应用的四个主要组件,它们是什么,以及它们如何一起工作以形成一个统一的 Android 应用。

Android 活动:表示层

Android 使用术语活动来描述用户看到的应用的“前端”屏幕。

活动是设计元素的集合,它们一起工作,组成应用的每个屏幕视图。这些元素包括用户界面元素、文本、背景图形、3D、前景内容、数字视频、弹出菜单、动画元素和其他视觉设计组件,这些元素用于在应用的功能(其活动)和使用应用的最终用户之间提供界面。我们在本书的前两部分详细了解了活动。

在 Android 术语中,活动通常由一个布局容器组成,它将一系列被称为小部件的用户界面元素,连同应用的内容一起,组织和排列到预定义的屏幕区域中。如果你想包含图形元素,让你的设计更引人注目,那么你可以使用 Drawables ,这是 Android 对图像或动画等图形元素的术语。

Android 中的动画同时使用了 Widgets 和 Drawablesdrawable 用于基于帧的动画(光栅动画),Widgets 用于基于程序或补间动画(矢量动画),drawable 也是如此。令人惊讶的是,Android 将动画准确地称为:动画。Android 中还有一个术语与其他编程语言中的术语相同: Events 。事件允许使用事件处理代码来处理组成我们活动的许多元素,就像在许多其他编程语言中一样。因为本书的读者熟悉编程,并且因为需要事件处理来使本书前半部分的用户界面设计具有功能性,所以我将在本书的早期介绍事件,这样我们可以更快地创建更健壮的应用。

我们将在第四章的中学习更多关于 Android Activity 类,以及通过 Android Layouts 设计屏幕布局,这利用了 Android ViewGroup 类。在第五章中,我们将通过 Android 小部件学习更多关于用户界面设计的知识,这些小部件利用了 Android 视图类。最后,当我们讲述在 Android 中使用数字图像、数字视频和动画的高级用户界面设计和图形设计时,我们将在第六章的中了解更多关于事件的信息,并在第七章到第十章的中了解更多关于的信息。

Android 服务:处理层

活动代表你的 Android 应用的前端或前台,而 Android 服务代表后端或后台处理,如果你愿意的话,是繁重的工作。

Android 服务类用于创建执行重复处理任务的 Java 类,通常通过称为循环的编程结构或通过数据获取过程(如流)在后台执行,同时用户通过其前端用户界面活动使用您的应用。一个很好的例子就是用户在使用你的应用时播放 MP3 音频文件。

Android 中的服务类有许多用途,明显和常见的用途是播放音频 MP3 和数字视频 MP4 文件以供娱乐,从远程服务器流式传输新媒体文件,将文本转换为语音(语音合成),在玩游戏时计算游戏逻辑,处理 Android Live 壁纸或 Android 白日梦,使用蓝牙或 NFC 在最终用户之间实时传输大型新媒体文件,运行拼写检查过程,任何过于复杂的数学计算,3D 渲染, 以及任何需要大量处理器开销(功率)的东西,这使得活动用户界面或内容变得生硬和不专业。

对 Android 开发人员来说幸运的是,大多数现代 Android 设备,如智能手机、平板电脑、电子阅读器和 iTV 电视机,都配备了双核(两个中央处理器,或称 CPU)处理器的最低硬件配置,现在更多的设备都配备了四核(四个 CPU)处理器,现在市场上也出现了八核(八个 CPU)处理器的 Android 设备。这意味着您的 Android 服务类有足够的处理能力来利用!

Android 服务类中更强大的选项之一是将您的后台处理服务放入它自己的线程(我喜欢称之为产卵,但在编程术语中它被称为进程),由于 Android 设备中存在如此多的 CPU,这实际上可以转化为您的服务类被分配了它们自己的 CPU 核心。

Android 还有许多专门的服务类,这些服务类已经是主要 Android 服务类的子类(我们将在第三章中学习这个 Java 术语)。例如,Android 开发人员也可以使用 SpellCheckerService、WallpaperService、TextToSpeechService、DreamService、IntentService、AccessibilityService、VpnService 和 AbstractInputMethodService 类。我们将在本书第十七章的中学习所有关于服务的知识。

Android 广播接收器:通信层

Android 通过广播接收器在其应用基础设施内部进行通信。

这些通常用于应用间的通信,以及为您的用户提供警告,很多时候来自 Android 操作系统或 Android 设备本身。例如,如果电话在响,或者如果平板电脑的电池电量即将耗尽,Android 操作系统会发送一个广播接收器,您的应用编程逻辑可以通过某种自定义操作做出响应。其他常见消息涉及用于拍照的相机、时区改变、数据下载完成、语言偏好改变、视频缓存完成并准备好回放等等。

与 Android 服务类似,广播接收器在后台运行,您可以配置您的应用代码来“捕获”您认为您的应用及其最终用户需要关注的任何类型的广播接收器。一旦您的代码检测到需要响应的广播接收器,它就可以在适当的活动中调用适当的用户界面元素,并提醒最终用户操作系统或设备状态的变化。我们将在第十八章中仔细研究广播接收机。

Android 内容供应器:数据存储层

Android 对一个常见的概念有一个独特的术语:数据存储。无论是存储在内存中、SD 卡上的文件中还是 SQLite 数据库中,Android 中存储的数据都可以通过内容供应器进行访问。

跨 Android 应用存储和共享数据的主要(也是最好的)方式是使用开源的 SQL 技术,这是 Android 操作系统的一部分。这是 SQLite 数据库管理工具包。Android 有一个专门用于 sqlite 数据库管理范例的完整包,名为 android.database.sqlite,,它包含了创建和访问 SQLite 数据库所需的一切。

Android 内容供应器 SQLite 数据库被 Android 操作系统广泛用于 Android 设备用户定义的数据存储。在本书的后面部分,我们将会了解一些对 Android 设备用户更重要的数据库,比如联系人数据库和日历数据库。还有新的媒体相关数据库,可以跟踪用户的图像、音频文件、视频素材和播放列表。

在第十九章中,我们将了解更多关于 Android 内容供应器的信息,并了解如何创建、填充、修改和删除 Android SQLite 数据库。

Android 意图:应用间通信

一个 Android 应用通过一个意图在它的主要组件之间通信。

例如,您可以使用意图在您的活动和服务之间进行通信,您可以做任何事情,从启动新的任务或活动,到向现有的任务发出新的任务指令。

Intent 对象保存关于哪个应用组件需要执行所需任务的信息。这包括需要采取什么动作来完成该任务,任务用来执行该动作的数据的定义,以及可选地,该数据的 MIME 类型和任何标志(设置)以及可能需要的其他可选数据或信息,以通过从一个 Android 应用模块发送到另一个 Android 应用模块的意图对象来完全传达确切需要完成的内容。是的,就实现而言,意图是 Android 操作系统中较为复杂的领域之一。

每种类型的 Android 组件、活动、服务或广播接收器都有自己的意图对象类型。这保证了意图不会混淆,并保持一切井井有条。因此,要通过意向启动服务,需要传递一个 context . start Service();Java 方法调用与您的意图。对于活动,使用 context . start Activity();Java 方法调用,对于广播接收器,使用 context . send Broadcast();Java 方法调用。我们将在第三章 (Java)和第十六章(意图)中了解这一切。

Android 清单:应用权限定义

最后,Android 利用术语 Manifest 来描述 XML 文件,该文件“引导”或定义并启动任何给定的 Android 应用。Android 使用 XML 来定义许多东西,就像用于启动网站的 index.html 文件一样,Android 应用通过他们的项目 APK 的 AndroidManifest.xml 文件启动。

在任何 Android 应用的根级别中。 APK (Android 包)文件,你会发现一个名为: AndroidManifest.xml 的文件,其中包含 xml 标记标签,这些标签定义了 Android 操作系统需要了解的关于你的应用的所有信息。这包括但不限于,应用支持哪些 Android OS 版本,应用包含哪些活动、广播接收器和服务,应用需要哪些权限来访问安全数据库和互联网资源,以及需要建立的意图过滤器。

我们将在需要定义特殊活动、服务、广播接收器或为应用组件分配权限的章节中讨论 Android Manifest。当我们读到这本书的结尾时,这将会是相当多的。

创建您的第一个 Android 应用

我们不要再浪费时间了,因为这一章我们有很多内容要讲,所以让我们直接进入正题,通过你在第一章中设置的快速启动图标启动 Eclipse。我们将在本节创建一个 Hello World 应用框架,我们将使用它来构建一个 world generation toolkit,您可以使用它作为创建自己的星际游戏的起点。

接受 Eclipse 在用户文件夹中为您设置的工作区文件夹的默认路径,并在屏幕上启动 IDE。进入文件菜单,找到顶部的子菜单,然后选择安卓应用项目 子菜单。

或者,你也可以使用文件image新建image项目。。。菜单顺序,这是 Android 4.2 之前的访问方式。这将打开一个新项目对话框,其中列出了您可以在 Eclipse 中创建的不同类型的项目。找到 Android 项目类型,点击左边的三角形 UI 元素打开 Android 应用类型的子菜单,然后选择 Android 应用项目,最后点击对话框底部的下一个image 按钮。

这两个工作流程都会打开新建 Android 应用对话框,在这里我们可以设置 Hello World Android 应用的所有顶级属性,如图图 2-1 所示。

9781430257462_Fig02-01.jpg

图 2-1。在 Eclipse 中新的 Android 应用对话框中命名我们的应用、项目和包

首先在对话框的第一个字段中输入应用名称,Hello_World。请注意,当您在 Hello_World 中键入时,第二个字段项目名称也是通过双重键入特性填写的。这意味着 Android 希望我们的应用名称和项目名称相同,正因为如此,我将在我们的 Hello World 应用名称中使用下划线而不是空格,因为这是一种相当常见的编程实践,也因为我不喜欢在我的文件名或文件夹名中使用空格。

第三个字段允许我们为我们的新 Android 应用项目创建我们的包名,为了对本书使用一致的包命名约定,让我们使用: chapter.two.hello_world 作为我们的包名,它应该使用所有小写字母和下划线。接下来,我们需要为我们的 Android 应用选择我们的最低要求 API 支持级别,我们将通过 Android 2.2 API 级别 8 设置将其设置为 9 个版本的向后兼容性,因为市场上仍有许多 Android 2.2 和 2.3.7 设备需要我们提供支持。我们还需要设置我们的目标 SDK 级别,这是我们正在开发的目标 Android API 级别,在这种情况下,它是 Android 4.1 API 级别 16,因为这是我们在第一章中安装的仿真器。我们将使用我们刚刚在第一章中安装的当前 Android 4.2 API Level 17 进行编译,因为这是我们拥有的最新(也是最无 bug 的)软件,并且您总是希望使用最新的开发软件代码进行编译。现在点击下一个image 按钮,进入下一个对话框,如图图 2-2 所示。

9781430257462_Fig02-02.jpg

图 2-2。新的 Android 应用–配置项目对话框,我们在其中选择创建新项目的选项

配置项目对话框中,勾选对话框顶部的创建自定义启动器图标复选框和创建活动复选框,以及对话框底部的在工作区创建项目复选框,然后点击image 旁边的进入配置启动器图标对话框,如图图 2-3 所示。

9781430257462_Fig02-03.jpg

图 2-3。在“配置启动器图标”对话框中,我们可以选择预定义的 Android 应用启动图标

此对话框允许您从图像、剪贴画或文本资源中选择预定义的 Android 应用启动图标,其中许多已经为您提供。现在让我们选择缺省值(正如我们在所有这些对话框中所做的那样),看看缺省的新 Android 应用项目创建过程是如何进行的,这样我们就有了一个最基本的理解。在你选择了你的应用启动器图标(Android 将它命名为 ic_launcher.png,我们将在本章后面看到)之后,点击下一个image 进入创建活动对话框,在这里我们将为我们的应用创建一个空白活动。我们选择了一个 BlankActivity ,这样我们就可以看到 Android 将通过新的 Android 应用项目系列对话框生成的最少代码。对话框如图 2-4 所示。

9781430257462_Fig02-04.jpg

图 2-4。新 Android 应用项目系列对话框中的创建活动对话框

你可能想知道 Android 中的 Activity 是什么,它的功能到底是什么。一个活动是一个包含内容和用户界面(UI)设计的屏幕区域,为您的应用提供一个前端(显示区域)来与您的最终用户进行可视化交互。正如您将在本章中看到的,主活动是通过 XML 标记定义的,然后通过 Java 代码在主活动类的应用 onCreate()方法中进行膨胀。该活动包含由 Android ViewGroup 类指定的布局容器(逻辑上布局是视图组),这些布局容器包含 Android View 类小部件,这些小部件是 UI 元素和内容容器。

点击下一步image 按钮,进入新建空白活动对话框,如图图 2-5 所示,我们将为我们的 Android 应用的活动设置参数,就像我们在第一个新建 Android 应用对话框中所做的一样。让我们接受默认的(建议的)名称,只是为了熟悉 Android 希望我们如何称呼应用的各种主要组件,并将我们的活动命名为 MainActivity ,将我们的布局 XML 文件命名为 activity_main ,导航类型为None——同样,这样我们可以看到新的 Android 应用项目系列对话框将为我们提供的最少的引导代码。现在点击完成并让 ADT 继续新项目的创建过程。

9781430257462_Fig02-05.jpg

图 2-5。新的空白活动对话框,我们在其中命名活动并选择其导航类型

单击最后一个对话框中的最后一个 Next 按钮后,Android 开发工具(ADT) 将检查您当前的安装(SDK 和插件设置),以确保您拥有创建您刚才指定的 Android 应用项目所需的一切。例如,如果您指定了 Android 2.2 到 4.1 支持,但只安装了 API 10 级(2.3.7)到 API 16 级(4.1.2),那么会出现一个安装依赖项对话框,要求您安装 API 8 级(2.2)。一旦你点击了 Install/Upgrade 按钮,这些额外的 API 将会从 Google 仓库中取出并安装在你的系统上,用于你的 Eclipse Android 开发配置。现在,我们准备在 Eclipse IDE 中开发新的 Hello World 应用,一旦安装依赖项下载完成(如果需要)并且其安装过程已经完成,它将出现,并填充有新的 Android 应用项目。接下来让我们看看 ADT 如此好心地为我们创建的 virgin Android 项目!

剖析一个 Android 应用项目

让我们看看 ADT 新的 Android 应用项目 helper 在我们的 Eclipse IDE 中为我们创建了什么,从 IDE 左侧的 Package Explorer 项目导航窗格开始。Package Explorer 实用程序允许我们在开发过程中的任何时候浏览 Android 应用的项目素材层次结构,就像 Windows Explorer 实用程序允许我们浏览硬盘驱动器和操作系统一样。图 2-6 显示了新项目在 IDE 的屏幕上弹出后 Eclipse 的样子。

9781430257462_Fig02-06.jpg

图 2-6。Eclipse 中显示了新的 Android 应用项目,打开了关键文件夹和子文件夹以显示项目素材

让我们通过点击指向右边的每个文件夹旁边的小三角形 UI 元素,打开您的 Hello_World 顶层项目文件夹中的一些关键子文件夹。现在,让我们把重点放在名为 src (源代码)和 res (资源)的文件夹上,因为它们是任何 Android 项目中最重要的文件夹。打开 src 文件夹,其中包含一个名为 chapter.two.hello_world 的子文件夹,您可能记得我们在新的 Android 应用对话框中将其指定为我们的包名。

再深入挖掘一下,在 chapter.two.hello_world 文件夹下,你会发现我们的MainActivity.java文件,其中包含新的 Android 应用创建过程为我们编写的 Java 代码,它“引导”或启动我们的活动(主屏幕)用户界面布局和菜单代码,这些代码恰好是通过布局菜单文件夹中的 XML 文件定义的。我们将在本章的后面部分打开这个 Java 文件,看看这个 Java 代码和它到底做了什么。您开发的任何 Android 应用的所有 Java 代码文件都将保存在这个 package-name 文件夹中。

还要注意图 2-6 中的,我点击了 MainActivity.java文件旁边的向右箭头三角形,包浏览器也显示了这个 Java 代码中的 Java 方法,所以看起来 Eclipse 包浏览器不仅导航文件,还导航代码结构。对于 IDE 来说,这是一个非常前卫的特性。

我们需要仔细查看的另一个主要应用素材文件夹是 resources(资源)或 res 文件夹,正如您可能已经猜到的那样,Android 应用不可避免地要利用它来创建用户体验(UX)的所有 XML 和新媒体资源都存放在这个文件夹中。点击 res 文件夹旁边的三角形 UI 图标,如图图 2-6 所示,打开它,你可以看到它的很多子文件夹都是新的 Android 应用项目助手为我们创建的。

您在顶部看到的前四个文件夹都以单词 drawable 开头,正如您可能猜对的那样,这是一个 Android 应用素材,可以通过我们之前了解的活动绘制到屏幕上。drawable 可以是图像、形状、帧动画、图像过渡、图标或任何类似的图形相关内容或应用所需的用户界面元素。还要注意,有四个可绘制的文件夹——每个文件夹对应一个屏幕密度级别:低、中、高、超高。值得注意的是,从 Android 4.2.2 开始,还有一个额外的超高(XXHDPI)分类。

单击任何一个(或者所有四个,如果你喜欢的话)可绘制文件夹旁边的三角形 UI 元素,你会看到 ic_launcher.png 启动器图标,这是我们在新的 Android 应用项目系列对话框的第三个配置启动器图标对话框中创建的。请注意,您只需将应用图标正确命名(ic_launcher.png)并放置在正确的 drawable 文件夹中,就可以为您的应用显示图标。没错:零编码。我们将在本书的第二部分讨论如何为这些不同的可绘制文件夹优化图标和图形。

这四个可绘制的文件夹允许 Android 开发者(比如你自己)在所有类型的 Android 设备上提供定制的像素级完美图形元素,从智能手机到平板电脑到电子阅读器到 iTV 电视机。低密度像素图像(LDPI) 针对最小的 Android 屏幕进行了优化,例如 120 DPI(也代表点每英寸)的翻盖手机或 MP3 播放器,它们通常具有 320 x240 像素的小屏幕。中等密度像素图像(MDPI)适用于使用 160 DPI 像素屏幕密度的入门级智能手机(480 x320 和 640 x480 分辨率)。

高密度像素图像(HDPI) 适用于主流智能手机和使用 240 DPI 像素密度屏幕的 5 英寸至 7 英寸迷你平板电脑(800 x480、854 x480 和 960 x540 分辨率)。超高密度像素图像(XHDPI) 使用 320 DPI 像素密度屏幕,适合高清智能手机和更大的 8 英寸至 11 英寸平板电脑(1024 x600、1280 x720 和 1280 x800 分辨率)。互动电视密度像素成像(TVDPI)也使用 320 DPI(分辨率为 1920×1080 和 1920×1200 ),适合新的谷歌电视 iTV 设置。我们将在本书的第二部分更详细地讨论这个主题,其中包括活动用户界面和内容开发的图形设计和动画。

下一个文件夹是布局文件夹;单击三角形 UI 元素将其打开,您将看到它当前包含我们活动的布局 XML 文件,命名为 activity_main.xml ,正如我们之前在新的 Android 应用项目系列对话框的第五个对话框中指定的。该文件包含所有定义活动屏幕布局及其用户界面元素的 XML 标记。我们将在本章的下一节在 Eclipse IDE 中打开它,并最终定制 XML 标记来创建一个更酷的 Hello World 用户体验。

您为应用定义的每个活动(用户界面屏幕)在这个布局文件夹中都有自己的 XML 文件,每个文件都包含定义每个应用屏幕外观的唯一标签。例如,如果你的应用有一个登录界面,那么这个文件夹中也会有一个 activity_login.xml 文件,它包含的 xml 标记与 activity_main.xml 文件完全不同。

下一个文件夹是 菜单文件夹,其中保存了定义每个活动用户界面屏幕的 Android 应用菜单结构的 XML 文件。单击菜单文件夹旁边的三角形 UI 元素将其打开,您将看到它当前包含我们活动的菜单 XML 文件,Android 已将其命名为 activity_main.xml ,如之前在我们新的 Android 应用项目系列对话框的第五个对话框中所指定的。

布局和菜单 XML 文件具有相同名称的原因是因为通常每个应用(活动)屏幕都有 UI 元素和菜单,所以对它们进行分组的最合理的方式是根据它们的文件名。因为这些文件在不同的文件夹中,它们被分开保存,因此可以有相同的文件名,Android 将通过使用文件名的第一部分以及它所在的文件夹来查找。我们将在本章的稍后部分在 Eclipse IDE 中打开这两个文件,稍后我们甚至将定制它们的 XML 标记来创建一个更高级的 Hello World 布局和菜单系统,这样您就可以更好地体验 Android 中的活动是如何工作的。

resource 文件夹中的最后三个子文件夹是 values 文件夹,其中保存了我们的应用的常量或“硬编码”值,例如字符串、主题、尺寸、颜色等,这样以后就可以在项目层次结构中的一个集中位置对它们进行访问(并且非常容易地进行更改)。Android 希望将所有值外化到这些文件夹中,我们将在下一节看到 strings.xml 文件。正如您将在整本书中看到的,如果您没有正确使用值,Eclipse 会在 IDE 中用三角形黄色警告图标标记您的代码。安卓操作系统有点严格!

接下来,让我们仔细看看 Android 如何利用 XML 标记来允许团队成员,主要是设计角色的非程序员,为应用开发过程做出贡献。XML 用于 Android 开发中的许多事情,例如用户界面设计、AndroidManifest.xml 文件中的应用配置等等。

Android 应用项目:XML 标记

您的应用在MainActivity.java中的 Java 代码引用了我们在布局和菜单文件夹中看到的 activity_main.xml 文件,事实上,当 Eclipse 在新的 Android 应用项目创建过程之后打开时,它会自动从其中央主编辑区域的布局文件夹中打开活动布局 xml 文件 activity_main.xml 。这可以在图 2-6 中看到,它展示了 Eclipse 第一次打开您的新应用项目时的样子。请注意,在图形布局编辑器(底部标签中的注释名称)的中心区域,activity_main.xml 已打开(顶部标签中的注释名称)。

使用 XML 在 Android 中创建用户界面屏幕布局

让我们点击 Eclipse 中央编辑窗格底部activity_main.xml 选项卡,如图图 2-7 所示,并查看这个 xml 标记在您的 Android 应用中是如何工作的。下面是定义相对布局容器并放置 Hello world 的 XML 标记!里面的文字:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world" />

</RelativeLayout>

9781430257462_Fig02-07.jpg

图 2-7。使用主编辑区右下方的 XML 编辑选项卡查看 activity_main 布局 XML

第一个 XML 标签显示在 < RelativeLayout > 标签中,它提供了一个布局容器,用于保存我们的用户界面元素,在本例中是文本,最后是图像和按钮。在 RelativeLayout 标记中,您会发现几个参数,每个参数都遵循以下格式:

`platform:feature="setting value"`

例如,第一个参数是 xmlns:android 并且引用了 XML 平台(xmlns 表示扩展标记语言命名模式)并且定义了互联网上的一个位置,在这个位置,在这个 XML 文档中使用的用于 android 的 XML 标签被公开定义并且在一个中心位置被引用。第二个参数 xmlns:tools 也来自 XML 平台,它定义了在互联网上公开定义这个 XML 文档中使用的 XML 工具的位置。 tools:context 标签告诉我们这些工具将在哪里使用,在这个例子中是在我们的 MainActivity Java 类中,通过引用。MainActivity 该参数内引号中的设置值。

布局 XML 文件中的其他参数都来自 Android 平台,并定义了与 Android OS 相关的参数,例如,android:layout_width 和 android:layout_height 都被设置为 match_parent 值,该值告诉相对布局容器扩展以填充整个显示屏。

现在让我们看看 < TextView > 标签中的参数,它在我们的相对布局容器中设置我们的文本。我们再次看到 android:layout_widthandroid:layout_height 参数,但是这一次它们引用了 wrap_content 设置,这实质上与 match_parent 设置完全相反。不是扩展标签来填充它的容器,而是“收缩包装”容器,或者在这个例子中是用户界面元素,围绕它的内容!接下来让我们看看 android:text 参数引用的布局居中参数和 string.xml 文件值。

Android:layout _ center horizontalAndroid:layout _ center vertical参数都被设置为 **true,**这表示我们希望将 TextView UI 元素水平和垂直居中,以便 TextView UI 元素位于活动屏幕的中心,而不管用户设备当时使用的屏幕密度、方向或分辨率如何。

TextView UI 元素的最后也是最重要的参数是该 UI 元素要包含的实际文本内容,这可以通过参数 android:text 来访问。引号中包含的设置值被设置为 @string/hello_world ,这是 Android OS 特定的符号表示法,用于:

C:\Users\Username\workspace\Hello_World\res\values\strings.xml <string> tag named: hello_world

使用 XML 在 Android 中创建选项菜单

我们将在本章后面的文件夹中查看 strings.xml 文件,看看这个文本值是如何设置的。首先,我们来看看菜单文件夹中包含的另一个 activity_main.xml 文件,分析一下 ADT 为我们编写的菜单 xml 代码。在你的包资源管理器中右键点击菜单文件夹中的 activity_main.xml 文件(如图图 2-6 所示),选择打开或者直接选择文件,用键盘上的 F3 键打开。第二个标签在 Eclipse 的中央编辑区打开,标签为 activity_main.xml ,你会看到 xml 标记定义了你的菜单设置条目,如图 2-8 所示。

9781430257462_Fig02-08.jpg

图 2-8。在 Eclipse 中央代码编辑区的第二个(菜单)activity_main.xml 选项卡中显示的菜单 XML 文件

Android 中的菜单 XML 文件也使用名为标签的标记结构,通过 <菜单> 标签容器和其中每个菜单项的 <项目> 标签来定义菜单项。在这种情况下,只有一个名为 Settings 的菜单项,但是,稍后我们会添加更多的菜单项并激活它们,这样你就可以完全理解如何在你的应用中实现菜单项。

值得注意的是,当你运行你的应用时,当你在 Android 模拟器中使用菜单键(按钮)时,菜单会弹出,即使菜单项被点击时不会做任何事情。这允许您定义活动菜单用户界面,并在编写代码实现它实际做什么之前测试它。现在让我们一行一行地看看 Android 为我们创建的菜单 XML 代码:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/menu_settings"
        android:orderInCategory="100"
        android:showAsAction="never"
        android:title="@string/menu_settings"/>

</menu>

正如您所看到的,任何 XML 文件中的开始标记,在本例中是“parent”<菜单> 标记,包含对 Android XML 命名模式的 HTTP 引用,就像我们前面看到的 activity_main.xml 文件的 < RelativeLayout > 文件夹版本中的布局标记一样。在<菜单>标签中,我们“嵌套”了定义每个菜单项的<项目>标签,而每个<项目>标签又有自己的参数,这些参数定义每个菜单项的名称、它在菜单上显示的内容、它出现的顺序,以及它是否在 Android 3.x、4.x 或 5.x 操作系统中显示为动作图标。让我们检查一下每个参数。

第一个 android:id 参数将这个菜单项命名为 menu_settings ,以便我们可以在 Java 代码中引用它。第二个 android:orderInCategory 参数设置菜单项在包含多个菜单项的菜单中的顺序,大多数菜单都是这样。当我们稍后添加菜单项时,我们将把这个参数设置为 200(以此类推),以确定我们添加的每个菜单项功能的重要性。

第三个 android:showAsAction 参数决定了你的菜单是否显示在 Android OS 版本 3.x 和 4.x(以及即将推出的 5.x)设备的动作图标栏上。在这种情况下,我们使用 none 设置,因为我们希望向后兼容 Android 1.6 和 2.x 设备,如亚马逊 Kindle Fire (2.3.7)。一个设置会在屏幕底部弹出菜单,当你稍后在 4.2 模拟器中运行 Hello_World 应用时就会看到。如果你是单独为 Android 3.x 和更高版本开发应用,你可以使用 ifRoom 参数作为设置,你的菜单项将出现在 Android 操作栏中,如果有空间的话。

最后一个 android:title 参数是弹出菜单中菜单项本身的标题或标签。因为这个菜单标题是一个字符串常量,所以它被设置在 strings.xml 文件的文件夹中。事实上,现在让我们通过右键单击 values 文件夹中的 strings.xml 文件并选择 Open 命令来查看一下!

使用 XML 为 Android 应用设置常量值

如图图 2-9 所示, strings.xml 文件在 Eclipse 的中央区域打开它自己的编辑标签,如果你想直观地看到编辑过的字符串,点击左边底部的资源标签或者使用右边的 xml 视图标签,标签为文件名 strings.xml

9781430257462_Fig02-09.jpg

图 2-9。XML 编码模式下 Eclipse central 编辑窗格中显示的 strings.xml 文件(位于 values 文件夹中)

因为我们在本章的这一节学习 XML 代码,所以我选择在 Eclipse ADT 编辑器中显示 XML 标记视图窗格,如图 2-9 所示。

现在让我们看看 XML 标记代码,看看我们是如何定义常量的:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Hello_World</string>
    <string name="hello_world">Hello world!</string>
    <string name="menu_settings">Settings</string>
</resources>

第一个 XML 标记声明我们使用的是 XML 1.0 版,并且我们使用的是文本(字体)编码范式 UTF-8,它支持跨越许多常见语言的相当大的字符集。第二个“parent”标签是保存嵌套在资源容器中的资源的标签。第一个 <字符串> 标签被命名为 app_name ,它的值保存应用的名称 Hello_World ,当我们运行它时,它出现在模拟器中应用的顶部。第二个 <字符串> 标记名为 hello_world ,它的值保存 TextView UI 元素中使用的文本,该元素显示: **Hello world!**当我们运行它时,它出现在模拟器的应用活动屏幕的中间。第三个 <字符串> 标记名为 menu_settings ,其值包含第一个菜单选项标题的名称: Settings ,当我们运行它并单击模拟器屏幕右侧的菜单按钮或图标时,它会出现在模拟器中应用的底部。

既然我们已经介绍了可以通过 Android 应用中的 XML 标记设置的大量选项和值,那么让我们看看 Java 如何通过各种 onCreate()方法调用、启动和膨胀所有这些 XML 素材。

Android 应用项目:Java 编码

现在让我们来看看 Android 应用 Java 代码素材本身,它们位于我们在本章前面详细讨论过的项目浏览器层次结构中。我们将再次从项目文件夹层次结构的最顶层开始,查看 src 文件夹,在我们的包文件夹下,我们将找到包含 MainActivity 类和 onCreate()方法的 MainActivity.java Java 源代码文件。

假设您的 src 和 package-name 文件夹已经打开,您可以看到 MainActivity.java 文件,单击MainActivity.java文件将其选中,并按下键盘上的 F3 键,或者您可以右键单击文件名,并从出现的上下文菜单中选择打开菜单项。第四个选项卡在 Eclipse central 编辑窗格的顶部打开,您应该会看到类似于图 2-10 中所示的内容。

9781430257462_Fig02-10.jpg

图 2-10。MainActivity.java 文件显示在 Eclipse central 编辑窗格中,准备进行进一步编辑

请注意,在 Eclipse 的中间部分打开了一个标签,在顶部写着MainActivity.java,并包含该文件中的 Java 代码。Eclipse 的核心部分是代码编辑窗格,可以同时打开多个选项卡,正如我们在打开布局和菜单 XML 文件进行查看和编辑时看到的那样。所以,现在让我们来看看我们的 Java 代码。

通过导入语句定义 Android 类

顶部有三个 import 语句,它们引用了我们将在 Java 类及其下面的方法中使用的其他 Java 代码。注意我们将在下一章更详细地讨论所有这些 Java 术语。要查看所有的导入语句,点击第一个导入语句旁边的 + UI 符号,就可以看到所有三个导入语句。

第一个 onCreate( ) 方法使用第一个 Bundle 类,第二个 Activity 类扩展我们的 MainActivity 类,第三个 Menu 类通过 onCreateOptionsMenu( ) 方法创建一个菜单。所有这些 Android 类在本书的前两部分都有更详细的讨论。下面是为 Hello_World 应用创建活动(用户界面)和菜单的 Java 代码,正如在 ADT New Android Application Project helper 中为我们创建的一样:

package chapter.two.hello_world;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_main);
       }
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
                getMenuInflater().inflate(R.menu.activity_main, menu);
                return true;
       }
}

使用 onCreate()方法创建我们的应用基础结构

接下来,让我们看看 Java 类的 MainActivity 和位于其中的 onCreate( ) 方法。在 Java 中,在类名前使用 class 关键字来声明一个类。在这种情况下,我们的类被称为 MainActivity,它可以被任何其他代码访问,因此它也被声明为 public,在 class 关键字之前使用 public 关键字。这个 MainActivity 类扩展了(或从其借用方法)Android 应用活动“超级类”,我们之前在代码顶部使用 **import android.app.Activity 导入了该类;**行代码。我们完整的 MainActivity 类声明如下所示:

public class MainActivity extends Activity { ... }

我们类中的第一个方法也是 public ,也声明为 void,,这意味着它不返回任何值给调用函数(在本例中是 Android OS),它只是做一些事情,在本例中是通过 onCreate( ) 方法创建我们的初始活动或用户界面屏幕。Android 操作系统向 onCreate()方法传递了一个名为 saveInstanceStateBundle 对象,它包含了我们活动中用户界面元素的状态(设置),以值和设置捆绑的形式。

onCreate()方法内部有两个方法调用。第一个方法调用使用 super 关键字将 saveInstanceState Bundle 对象向上传递给 android.app.Activity 超类及其 onCreate()方法。第二个方法调用通过 setContentView( ) 方法为应用设置内容视图(活动屏幕),同时引用本章前面提到的 layout 文件夹中的 activity_main.xml 文件。那看起来是这样的:**setContentView(r . layout . activity _ main);**其中 R 等同于 Hello_World 项目路径,向下到 layout 文件夹,或者 C:\ Users \ Username \ workspace \ Hello _ World \ RES \因此您可以从这些信息中进行推断, R.layout.activity_main 实际上转化为(意味着 Android):

C:\Users\Username\workspace\Hello_World\res\layout\activity_main.xml

这用于通过活动子类中的 Java setContentView( ) 方法加载您的 XML 布局定义(记住我们的类声明的扩展活动部分)。接下来,让我们看看第二个方法 onCreateOptionsMenu( ) ,它同样用于从 activity_main.xml 菜单 xml 文件创建您的活动的选项菜单,使用的 getMenuInflater( ) 方法通过我们前面看到的Android . view . Menuclassimport语句访问。

getMenuInflater()方法调用一个**。inflate( )** 方法有两个参数,一个是通过 onCreateOptionsMenu(菜单菜单)传入该方法的名为菜单菜单对象,另一个是通过我们现在熟悉的 R.menu.activity_main 传入菜单文件夹中 activity_main.xml 文件的路径,相当于:

??C:\Users\Username\workspace\Hello_World\res\menu\activity_main.xml

所以基本上。inflate()方法获取名为菜单菜单对象,并用 R.menu.activity_main 中引用的 XML 菜单定义对其进行膨胀。注意,Android 使用文件名的第一部分(不是。xml 部分,它不使用文件扩展名)来引用 XML 和图形(可绘制)文件。一旦菜单对象 Menu 膨胀并准备好使用,它就向操作系统返回一个值。

在 Android 4.2 模拟器中运行你的 Hello World 应用

现在让我们编译并运行所有这些 XML 和 Java 代码,看看它在我们在第一章为 Nexus S 智能手机创建的 Android 4.2 模拟器中做了什么。要启动模拟器,只需在 Eclipse Package Explorer 中右键单击 Hello_World 项目顶层文件夹,并选择Run AsimageAndroid Application菜单项。当 Nexus S 智能手机的 Android 4.2 模拟器出现时,您将看到 Hello_World 应用及其 Hello world!仿真器屏幕上的感叹号如图图 2-11 所示。

9781430257462_Fig02-11.jpg

图 2-11。在 Android 4.2 Nexus S 智能手机模拟器中运行 Hello_World Android 应用

我们可以在新的 Android 应用项目系列对话框中看到我们指定的应用名称,以及我们选择的启动图标和我们在 strings.xml 文件中设置的文本消息。我们的 XML 布局标记完美地将文本居中,现在我们准备单击右上角的 X 并退出模拟器。

在第一次 Android 4.2 仿真后设置 Logcat

一旦您第一次退出 Android 4.2 Nexus S Smartphone 模拟器,您会注意到出现一个错误对话框,通知您没有为您的 Eclipse Android 开发环境设置 Logcat,并提供为您设置它。该自动监控 Logcat 对话框如图图 2-12 所示。

9781430257462_Fig02-12.jpg

图 2-12。在 ADT 中首次启动任何仿真器后出现的自动监视 Logcat 对话框

Android 的 Logcat 代表 Log Catalog,是一个自动日志记录系统,为您提供了一种方便的方法来收集和查看所有 Android 系统调试器输出。来自各种应用和操作系统各部分的详细日志被收集在一系列循环缓冲区中,然后可以通过 Eclipse IDE 中的 Logcat 窗格查看甚至过滤这些日志。

一旦您成为更高级的 Android 开发人员,您也可以从 ADB shell 使用 Logcat 来查看日志消息。更多信息可在以下网址找到:

[`developer.android.com/tools/help/logcat.html`](http://developer.android.com/tools/help/logcat.html)

您会发现 Logcat 实用程序有助于研究应用开发过程中可能出现的错误。如果您将 Eclipse Logcat 窗格中的错误消息剪切并粘贴到 Google 搜索栏中,然后按 Return 或单击 search,您可以很快找到其他开发人员,他们的应用中也出现了同样的错误消息,并查看他们是如何解决的。

摘要

在这一章中,你创建了你的第一个 Android Hello World 应用,在 Android Developer Tools (ADT)新的 Android 应用项目“helper”系列对话框的帮助下。在接下来的章节中,我们将修改这个基本代码来构建一个更令人印象深刻的 Hello World 应用,这样您就可以将您对 Eclipse、XML 标记和 Android 中的 Java 编码的了解提升到一个新的水平。

我们首先关注的是通过一些对话框创建新的 Android 应用项目的工作流程,这些对话框允许开发人员设置无数选项来创建“引导”应用外壳,然后他们可以修改并变形为他们想要开发的应用。这包括命名应用、Java 类和 XML 文件、确定 Android OS 版本支持、选择应用启动图标、命名和选择活动类型以及选择导航模式。

接下来,我们查看了 Eclipse IDE 及其非常有用的 Package Explorer 窗格,并使用该实用程序检查了新的 Android 应用项目助手为我们创建的 Android Hello_World 应用结构的剖析。我们查看了源代码和资源文件夹层次结构,以及图形素材、XML 定义和 Java 代码的文件保存位置。

接下来,我们打开了用于 Hello_World 应用项目的布局、菜单和字符串常量定义的关键 XML 文件,并研究了它们的功能:标记和参数。我们了解了 Eclipse center 代码编辑窗格以及顶部和底部选项卡区域,这些区域允许我们选择正在工作的文件和编辑模式。

接下来,我们打开了我们的主 Java 类文件,看了看 Java 代码如何将我们的用户界面、菜单和内容的 XML 定义组合在一起,并了解了一些核心 Android 类,如 Activity、Bundle 和 Menu 类。最后,我们第一次在我们在第一章中设置的 Android 4.2 Nexus S 模拟器中运行了我们的 Hello_World 应用,并允许 ADT 在我们退出模拟器时为我们设置 Logcat。

在下一章中,我们将通过添加和更改 ADT 为我们创建的初始代码,并添加我们自己的内容、用户界面元素、图标和菜单选项,将我们的 Hello_World 应用提升到一个新的水平,以了解如何使用 ADT 为我们创建的引导应用,并将其转化为定制的东西,以实现我们自己的 Prime 指令。与此同时,我们将了解更多关于 Java、XML、图标和其他在前两章中没有揭示的 Android 秘密。

三、面向 Android 入门的 Java:增强我们的 Hello World 应用

在这一章中,我们将使用新的 Android 应用项目助手,使用我们在上一章中创建的 Hello World 应用,并添加我们自己的 Java 代码,使它更有趣。同时,我们也将利用这一章,通过 Java 编程语言及其对象、变量、方法、类、包、修饰符等等,向那些不是 Java 程序员的读者提供本书中使用的各种代码结构的高层次概述。

我将尝试无缝地融合这两个目标,增强我们的 Hello World 应用,并在一个高层次上总结 Java 概念,形成一个有凝聚力的章节,在我们的 Hello World 应用的上下文中定义 Java 的方法和功能。使用 Java 代码,我们将为我们的 Hello World 应用添加功能,以便它生成新的世界,并开拓和保护它们。

Java 的最高层次:应用编程接口

与任何编程语言一样,该语言的最高级别被称为 API ,或应用编程接口 ,这是整个编程语言本身的总和,在其最新修订版中,都在一个集合或位置中。众所周知,如果您想使用任何给定的编程语言进行开发,您必须去获取(并最终学习)该编程语言的 API,以便使用其开发范式在该编程语言下开发应用。

在这方面,Java 和其他编程语言没有什么不同。在本章的剩余部分,我们将讨论 Java 的行话,以及它的各种编程结构,就像我们在前一章讨论 Android 中各种模块使用的行话一样。通过这种方式,你将在概念上了解我们在本书剩余部分所讨论的内容。

组织 Java API:包

Java 提供了一种将编程项目中的代码组织成逻辑模块或代码集合的方法,称为。在 Java 编程语言中,一个是 Java 的集合,我们将在本章的下一节更详细地了解它。

我们已经在 Eclipse 中为我们的 Hello_World 项目创建了一个,在我们在第二章中使用的新的 Android 应用项目系列助手对话框中。这五个对话框用于帮助创建 Hello World 应用的基本 Java 和 XML 代码基础。

因为我们在本书的第二章中创建了 Hello_World 应用,所以我们在逻辑上将我们的 Java 包命名为: chapter.two.hello_world ,然后在我们的MainActivity.java文件的顶部声明它,Java 代码如下:

package chapter.two.hello_world;

包是在每个 Java 代码模块的顶部被声明的,这些 Java 代码模块利用了包含在这些包中的方法(稍后会有更多的介绍)。包总是使用 Java 的关键字来声明。

项目包名称通常使用小写字符,并告诉用户包中的代码是做什么的。由于这个原因,我们需要使用逻辑包命名约定来告诉我们包的其他用户这个包是什么,如果可能的话,它是做什么的。

注意,包含功能类的包,尤其是在 Android 中,有时会在包中的姓氏上使用大写字母。你会在 Android 操作系统中经常看到这种情况,因为类是用大写字母命名的,比如 **String、View、Activity、Object、Bundle、**等等。

我们之前在第二章中创建的 chapter.two.hello_world 包目前包含一个名为 MainActivity 的类,其 Java 源代码位于我们项目的源代码文件夹(名为 src)下的一个名为MainActivity.java的文件中。在这一章中,我们将从头开始创建另一个全新的类,名为 WorldGen ,它将允许我们为 Hello World 应用创建新的世界(行星),同时也教授您基本的 Java 概念,以防您不是 Java 程序员。

随着您使用越来越多的 Android 操作系统特性,您会发现 Android 中的包名总是逻辑地反映出该包是什么,它做什么,以及该包在 Java 和 Android 操作系统层次结构中的位置。

让我们更仔细地看看这个,例如,使用 Android 包,我们已经用 Java 导入语句将这些包带入到我们的第二章 Java 代码中。这些导入语句位于我们的 MainActivity Java 代码文件中,就在我们的声明语句下面:

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

Java 中的导入命令用来你猜对了导入其他 Java 包。导入的包是逻辑上捆绑在一起的功能类的集合,这些功能类已经为您编写和测试过,并且当前可以在您的应用中用于商业用途。

在 Android OS 应用开发的情况下,import 语句允许我们使用预先存在的 Java 代码(保存在包中),这些代码是专门为支持 Android OS 功能而编写的,这些代码是为在我们的 Android 应用中使用而提供的,随着我们越来越多地使用这些包,我们将在本书中更详细地了解这些功能。

Java 最强大的一点是,我们可以导入已经编写和测试过的代码的整个库或包,然后在我们自己的 Android 应用中为我们自己的利益(甚至是利润)使用它们,而不必为该软件的(代码)开发支付一分钱。如果你仔细想想,这是一个相当惊人的开源软件开发商业提议。

让我们仔细看看这三个引用核心 Android 包及其类的导入语句,它们是在 Eclipse ADTNew Android Application Project 系列对话框期间在我们的 MainActivity.java 文件中为我们创建的,我们在第二章中使用了这些对话框。

查看 Java 导入语句

第一个, android.os.Bundle 引用了 Android OS。中间的引用告诉我们代码与操作系统相关,包名最后部分的 Bundle 告诉我们这个包是与 Android 中的 Bundle 特性相关的 Java 类和方法的集合。

第二个导入语句, android.app.Activity 也是 android 相关的。第二部分告诉我们它与 app 的应用功能有关,包名的最后一部分告诉我们这个包包含了一个类和方法的集合,用于提供 Android 中的活动功能。这个包是一个重要的包,在所有的 Android 应用中都有使用。接下来的几章将特别关注活动。

最后的导入语句, android.view.Menu 是一个与视图(屏幕相关)android 功能相关的 Android 包。它支持大量的视图类(以及叫做小部件的子类,我们将在接下来的几章中学习)。Android View 类与 Android View (屏幕布局和用户界面小部件)特性相关,我们将利用其中的许多特性来增强我们的 Hello_World 用户界面设计和用户体验功能。但是首先我们需要学习一点关于 Java 编程语言和 Java 对象的知识。在这种情况下,我们从 android.view 包中导入 Menu 类和方法,这样我们就可以实现我们的菜单系统。

Java 的基础:对象

Java 是一种面向对象编程 语言。像 C++ 一样,Java 使用被称为对象的编程结构来建模其编程逻辑中使用的数据和函数。Java 对象就像是你在日常生活中看到的现实生活中的对象的描述。

就像您每天遇到的现实生活中的对象一样,如汽车、电器、计算机、建筑物、船只、飞机等等,Java 对象也具有独特的属性和用途(即,可以增强您日常生活的功能),与您每天使用的那些现实生活中的对象非常相似。

在 Java 中,为了“建模”或创建一个对象,您将创建一个 Java ,它保存该对象的状态行为。我们将在本章的下一节学习更多关于的知识,但是要理解类,我们必须首先理解对象,所以让我们在这里更详细地讨论对象。

一个对象的功能可以通过它的行为来描述;也就是对象可以做或执行的那些事情。对象通过被称为**方法、**的编程结构获得这种功能,我们将很快在本章后面的 Hello World 应用中了解和使用这些方法。

对象的每个特征可以通过状态来定义;即描述任何给定时刻的对象属性的数据。对象通过被称为**实例变量、**的编程结构获得这些属性,我们将在本章后面的应用中学习和使用它们。

让我们以 Hello World 应用为例,定义一些世界或星球,每个世界或星球都将被表示为一个对象,这样您就可以看到这些概念在起作用。

首先,让我们定义一些我们的世界对象的属性或状态:

  • 行星名称 一个字符串数据类型或文本值,例如,“地球”
  • 行星质量 一个代表 Yottagrams 的整数值;地球是 5973 YG
  • 行星重力 一个真实的或浮动的重力值;地球=9.78 米/秒的平方
  • 行星殖民地一个整数数据值,代表一个殖民地的数量
  • 行星人口 一个 64 位的值,代表一个人的数量
  • 行星基地??整数值,代表军事基地的数量
  • 星球军事 一个整数值,代表军事人员的数量
  • 行星保护 一个布尔值,告诉我们行星力场是否开启

接下来,让我们定义至少十几个可以归因于这些新世界对象的对象行为或功能:

  • WorldGen 构造新的世界,即生成一个新的世界对象
  • 设定行星殖民地 在行星表面增加任意数量的新殖民地
  • 获取行星殖民地 返回行星表面的殖民地数量
  • 设定星球军事 在星球表面增加任意数量的军事基地
  • 获取星球军事 返回星球表面的多个军事基地
  • 开启力场 开启力场保护星球大气)
  • 关闭力场 关闭力场保护行星大气层
  • 获取力场状态 返回力场状态开/真或关/假
  • 设定殖民地移民 将人添加到星球表面的每个殖民地)
  • 获得殖民地移民 返回当前星球表面的人口
  • 设置基地保护 增加军事来保护星球上的军事基地
  • 获得基地保护 返回一个星球上的军事人员数量

正如你所看到的,这些是每个新的世界对象可以做的,或者可以改变的关于它的存在和状态或特征的行为或事情。

正如你将在本书后面看到的,在对象层次结构中,对象也可以包含其他对象。例如,这类似于系统硬盘上的文件夹层次结构。这允许更复杂的对象以更有组织和逻辑的方式模块化地构建。

在我们的 Hello World 应用示例中,这个概念的一个例子是 WorldGen 对象(我们在本章中定义和创建它)与 java.lang.Object 顶级对象一起使用,并增加了它的复杂性,我们将在本章的下一节中了解更多。

面向对象编程(OOP)的核心概念之一是数据封装、的概念,其中对象的状态或其实例变量只能通过其自身的函数或方法来改变。

数据封装的原因是,对象是自包含的,可以在真空中创建和测试,而不受正在创建的整个软件包中任何其他内容的影响。

这允许实现模块化代码开发过程,通常被称为代码模块化。在自包含代码模块中编写代码使得 bug 和其他问题更容易被隔离,在逻辑上有组织的功能中,每个功能在整个软件开发项目中单独开发。

这种代码模块化非常适合于最大化代码重用,因此允许软件开发团队在整个软件包开发过程中专注于开发他们自己的模块和功能。这样,一旦代码模块被编写、测试、调试,并最终发布供所有其他团队成员使用,每个人的编码工作就可以被其他团队成员使用。

Java 对象的蓝图:类

Java 中为 Java 对象编写蓝图的主要工具被称为,一旦 Java 类或 Java 包形式的类集合被发布使用,甚至更复杂的类或包也可以通过称为子类化的过程使用这些代码来创建。

在 Java 中,这是被称为继承的 OOP 概念的一个例子,其中一个现有的 Java 类可以在以后被用来创建那个原始类的一个更详细或更复杂的版本。子类的其他常用术语有:类、派生类和扩展类。

从原始类的派生(或从原始类的派生)的新类被称为子类,原始的“父”类被称为超类。超类可以通过 super 关键字在它们的子类中被引用,这一点我们将在本书中看到。超类的其他常用术语有:父类基类

这个类层次结构可以在 Android 开发者网站上的任何给定 Android 类描述网页的顶部看到,其中显示了每个 Android 类起源的层次结构,从顶级 java.lang.Object 超类开始,向下通过子类的层次结构,每个子类都是为了向其上的超类添加一些附加特性和功能而创建的。

java.lang.Object > Object Subclass > Subclass Subclass > etcetera

因此,如果您想查看每个类级别的特性添加到了哪里,从 java.lang.Object(对象特性的来源)开始,沿着树向下查看每个级别的子类。

让我们看一个 Java String 数据类型类的 Android 类层次的例子。这个类起源于 java.lang.Object 类,因此 Android java.lang.String 类继承了 Object 类,为 java 和 Android 增加了字符串数据类型功能。我们将使用 String 数据类型为我们将要创建的 WorldGen 对象定义 planetName 实例变量。

String 对象允许通过 char (character) 原始数据类型创建文本的数组(集合)。因此,字符串数据类型对象实际上是字符的集合(通过数组)(通过 char 数据类型),而 Java 中所有其他常见的数据类型被称为原语或原语数据类型。代码中的小写字符串不会代表 Java 的字符串数据类型,而会被认为是一个对象或变量名,所以如果您使用大量文本,这是需要注意的。

总而言之,只要记住顶级的 java.lang.Object 或 java 语言对象类是所有 Java 类的母体,因为它为 Java 中的所有对象提供了基础,无论它们是大是小。现在,让我们继续学习如何编写这些 Java 类,这样我们就可以用它们来产生或创建或实例化一些新的 Java 对象!

正如蓝图定义了任何给定的结构将如何构造一样,Java 也定义了一个对象将如何构造。一个 Java 类由保存对象状态值的实例变量、构造每个新对象的构造器以及操作其变量的方法组成,这样对象就可以拥有一些功能。同样重要的是要注意,在方法内部定义的变量被称为**局部变量,**而在方法外部但在类结构内部定义的变量被称为实例变量。

你可能会想,如何用一个类创建一个对象呢?在定义了对象的状态(实例变量)和它的功能(方法)的类被编码之后,我们可以利用这个类定义来创建一个对象的实例。一个实例是该对象的单个出现,并且该 Java 对象的每个实例化或出现可以是该特定对象的状态或属性的唯一且不同的集合。

使用上一章的 Hello World 应用示例,让我们创建一个新的类,为现有的 Hello World 应用生成新的 World 对象。为了声明这个我们称之为 WorldGen 的类,我们将使用下面的 Java 语法:

public class WorldGen { instance variables and methods go between curly brackets }

就像在任何其他编程语言中一样,我们首先要在 Java 类的顶部声明的是实例变量,我们将用它来保存我们的 WorldGen 对象的属性或状态。在 Java 中,这是通过使用以下通用格式来完成的:

<data type> then <variable name> then = then <set variable value> then;

因此,对于我们在上一节中描述的对象状态实例变量,我们将编写如下的变量描述代码行:

String planetName = "Earth"; (shown only to demonstrate how to set a default value)
int planetMass;
double planetGravity;
int planetColonies;
long planetPopulation;
int planetBases;
int planetMilitary;
boolean planetProtection;

我们在上面为 planetName 字符串变量使用了一个默认值,该值将应用于 planet Earth 向您展示如何在您的类变量声明中包含一个默认初始值。当你包含一个缺省值时,就像任何编程语言一样,它被称为初始化那个变量。通常,你可以声明变量,然后通过你的构造函数方法来设置它们,我们将在下一节看到。

如果您是一名程序员(我们假设您是),您已经熟悉了字符串(文本)整数(非十进制整数)双精度(最多 64 位值实数,或十进制数) long (最多 64 位值高精度数) charboolean (真/假值)数据类型

现在我们已经定义了对象的状态或实例变量,接下来让我们继续定义对象的行为,使用一些 Java 方法

定义 Java 对象的函数:方法

为了在你的 Java 类中定义一个函数或者方法,你可以使用下面的格式在你的 Java 代码中命名并且声明那个方法:

<Modifiers> <Return Data Types> <Method Name> (parameters) {Java code}

方法通常在类中的实例变量声明之后(虽然它们不是绝对必须的,但对于代码的其他查看者来说,这只是为了更好的代码组织和可读性的一个约定)。

对于我们之前描述的行为或函数,一个 WorldGen 构造函数和 11 个方法将声明如下(接下来我们将编写它们的功能):

public WorldGen            (String name, int mass, double gravity) {...}
void setPlanetColonies     (int numColonies) {...}
int  getPlanetColonies     () {...}
void setPlanetMilitary     (int numBases) {...}
int  getPlanetMilitary     () {...}
void turnForceFieldOn      () {...}
void turnForceFieldOff     () {...}
boolean getForceFieldState () {...}
void setColonyImmigration  (int numColonists) {...}
long getColonyImmigration  () {...}
void setBaseProtection     (int numForces) {...}
int  getBaseProtection     () {...}

在 Java 中,直接放在方法名前面的关键字叫做修饰符。Java 中的修饰符可以和类、方法或变量一起使用。如果需要,可以有多个修饰符来定义类、方法或变量的特征。有两种类型的修饰符,访问控制修饰符,以及不定义任何访问控制的修饰符。

有四个级别的访问控制修改: no modifier (见所有前面的方法,除了构造函数方法)其中方法或变量对包含它的整个包是可见的; public 修饰符,这意味着任何 Java 类,甚至是包外的类,都可以使用该方法或变量;私有修饰符,这意味着只有定义了方法或变量的类才能使用该方法或变量;和 protected 修饰符,这意味着该方法或变量对包以及所有可能从该类创建的子类都是可见的。

还有其他几种不影响访问控制的修饰符,比如:静态最终摘要、同步修饰符。

除了修饰符之外,还有在 Java 方法之前声明的返回数据类型。我们在许多方法中使用的 void 数据返回类型表示,当调用 void 方法时,所有这些方法都不会向调用实体返回任何数据值。我们正在使用的其他返回数据类型, int , **long,**和 boolean ,分别将数据返回给精确原始数据类型的调用实体。

现在让我们看看如何通过花括号中的代码为这些方法添加一些功能,花括号定义了每个方法的开始和结束。第一个 WorldGen( ) 方法是一种特殊类型的方法,称为构造函数,这个方法代码编写如下:

public WorldGen (String name, int mass, double gravity) {
        planetName = name;
        planetMass = mass;
        planetGravity = gravity;
        planetColonies = 0;
        planetPopulation = 0;
        planetBases = 0;
        planetMilitary = 0;
        planetProtection = false;
}

Java 构造函数与方法有许多不同之处。首先,它不使用任何数据返回类型,比如 voidint ,因为它是用来创建一个对象,而不是执行一个函数。事实上,这就是为什么它首先被称为构造函数;因为它的功能仅仅是构造或创建新的对象。

注意,每个创建 Java 对象的类都有一个与类同名的构造函数,所以构造函数是一种方法类型,它的名字可以(并且总是)以大写字母开头。

构造函数和方法的另一个区别是构造函数不能有非访问控制修饰符,所以一定不要将构造函数声明为:静态最终抽象同步

在这个 WorldGen()构造函数中,我们为新行星的名称、质量和重力获取三个重要的参数并在构造函数方法中设置它们。我们还将初始化其他对象实例变量为零,以创建一个干净,处女,无保护的世界。

接下来,让我们编写另外六个方法,它们执行那些修改我们世界状态的功能。这为 Hello_World 应用的用户提供了许多有用的构建世界的功能。

第一个 setPlanetColonies( ) 方法比我们的 WorldGen()构造函数方法简单得多,它允许我们向我们的世界对象添加新的殖民地。这个方法的 Java 代码编写如下:

void setPlanetColonies (int numColonies) {
        planetColonies += numColonies;
}

在我们的 setPlanetColonies()方法名之前声明的 void 数据返回类型声明了该方法将返回什么类型的值。在这种情况下,这个方法根本不返回任何数据值,所以我们将它声明为 void(或者没有任何数据返回类型或数据值)。

还要注意,我们的方法名以小写字母开头,对于方法名内部的单词使用大写字母。在计算机编程行业,这种命名约定被称为 CamelCase

在我们的 setPlanetColonies( ) 方法主体中,我们将利用一个赋值操作符,它将 numColonies 整数参数添加到该对象的 PlanetColonies 实例变量中。作为程序员,我们知道这是将传入方法的菌落数参数添加到 Planet Colonies 实例变量中保存的行星菌落总数的一种快捷方式,我们在 WorldGen 类的开头声明了该变量。

我们将使用 setPlanetMilitary( ) 方法做一些非常类似的事情,一旦我们用 Eclipse 对其进行编码,它将看起来像这样**,**:

void setPlanetMilitary (int numBases) {
        planetBases += numBases;
}

接下来**,,** s 写 turnForceFieldOn( )turnForceFieldOff( ) 方法,设置布尔参数**,表示一个星球的保护力场是开还是关。默认情况下正如我们从 WorldGen( ) 构造函数方法的主体中可以看到的,我们在行星最初被创建(实例化),**时将它的 planetProtection 变量初始化为 false,这样行星最初不会受到任何力场的保护。

void turnForceFieldOn () {
        planetProtection = true;
}
void turnForceFieldOff () {
        planetProtection = false;
}

现在让我们编写我们的**setcolonimigration()**方法,它允许我们将殖民者添加到我们世界的殖民地中。该方法使用加法赋值运算符将传递给该方法的殖民者数量参数添加到 planetPopulation count 实例变量中。

void setColonyImmigration (int numColonists) {
        planetPopulation += numColonists;
}

最后,让我们编写我们的 setBaseProtection( ) 方法,它允许我们将军事力量添加到我们的世界军事基地中。这个方法使用加法赋值操作符将传递给它的部队数量参数添加到 planetMilitary count 变量中。

void setBaseProtection (int numForces) {
        planetMilitary += numForces;
}

现在我们准备在 Eclipse ADT 中打开我们的项目,并创建我们新的 WorldGen Java 类。我们将把之前开发的所有代码都写入 Eclipse central 文本编辑器窗格,这样我们以后就可以在我们的应用中使用它来创建、填充和保护新世界。

在 Eclipse 中编写 Java 类:创建 WorldGen 类

首先,我们需要通过单击我们在第一章中设置的快速启动图标来启动 Eclipse ADT,并接受我们项目的默认工作区文件夹位置,它应该是 C:/Users/YourName/workspace/或类似的位置,当然,除非您已经将其设置为不同的位置。

一旦 Eclipse ADT 打开其主 IDE 窗口,您将看到我们在第二章中创建的 Hello World 项目。对于我们在第二章中使用的 Java 和 XML 编辑窗格,标签页应该仍然是打开的。

因为我们创建的 MainActivity 类包含用于启动应用主活动窗口的 Java 代码(以及它的名字),所以我们将利用 Java 的模块化特性,创建我们自己单独的 WorldGen 类来生成(衍生)世界对象。

创建我们新的 WorldGen Java 类

Java 是模块化的一个主要原因是允许我们通过其逻辑功能来组织代码,这样我们就可以编写类来创建我们的新世界对象,并拥有启动和定义我们的用户界面和内容活动屏幕的其他类。

要在 Eclipse ADT 中创建一个新的 Java 类,使用文件image新建image菜单序列,这将打开新建 Java 类对话框,如图 3-1 中的所示。

这个新的 Java 类对话框包含大约十几个字段、复选框和单选按钮,允许我们以类似于新的 Android 应用项目对话框允许我们在配置新的 Android 应用项目设置时所做的方式来配置新的 Java 类。

9781430257462_Fig03-01.jpg

图 3-1。使用新的 Java 类对话框创建我们的 WorldGen 类

当对话框打开时,您会看到它已经自动填充了几个字段;前两个设置是正确的,包括您的包名和 Hello_World 源代码文件夹位置。超类字段被设置为您的 MainActivity 类(该对话框将假设一个现有的 Java 类将被用作超类),因此我们希望将其设置为 java.lang.Object 类,因为我们的 WorldGen()类将生成世界对象,而不是活动。

首先,使用名称:字段将您的类命名为 WorldGen ,然后单击浏览。。。按钮,位于超类字段的右侧,这样我们可以浏览 Android 中所有可用的类,找到我们想要从中继承 WorldGen 类的 Java Object 类。

这将打开超类选择对话框,在这里我们开始在对话框顶部的选择类型:字段中输入单词对象,如图图 3-2 所示。在我们键入“o”字符后,对话框中间的**匹配项目:**部分填充,然后我们可以选择(单击)对象项目,如图所示。最后点击底部的 OK ,我们的 java.lang.Object 超类就定义好了。

9781430257462_Fig03-02.jpg

图 3-2。使用超类选择对话框浏览 java.lang.Object 类

在你点击 OK 之后,你将返回到 New Java Class 对话框,在这里你可以点击 Finish 来创建你的新的 WorldGen( ) Java 类。Eclipse 将新的 Java 类文件、代码和信息添加到它的三个主要窗格中:左边的 Package Explorer 窗格、中间的代码编辑窗格和右边的代码大纲窗格,如图 3-3 所示。

9781430257462_Fig03-03.jpg

图 3-3。 Eclipse ADT IDE 具有通过“新建 Java 类”对话框创建的空 WorldGen 类代码结构

注意在代码编辑窗格的顶部,新的 Java 类对话框也为您编写了您的 Java 语句,以及您的 WorldGen 公共类声明,这意味着我们已经准备好添加我们在本章的上一节中编写的 Java 代码。

请注意,我们将我们的 WorldGen 类公开,这样任何 Java 类,甚至是没有包含在我们的包中的 Java 类,都可以调用或调用我们的 WorldGen 对象构造函数,以及我们的 WorldGen 方法,这允许其他 Java 包也为它们的应用创建新的世界。

我们也可以将 public 修饰符完全从这个类声明中去掉,这将向 Java 编译器表明只有我们的 chapter.two.hello_world 包中的类才能生成新的世界。在这种特殊的情况下,这对于我们的应用来说同样适用,因为 MainActivity 类也在我们的包中。事实上,你可能会有兴趣在以后的某个时候尝试一下(去掉 public 修饰符)来获得更多的经验。

现在,让我们在 IDE 中央的 Eclipse ADT 编辑窗格中输入我们在本章前两节中创建的所有 Java 代码。或者,作为一种快捷方式,您可以剪切并粘贴它。确保所有内容都在定义 WorldGen 类边界的两个花括号(也称为大括号)内。

结果显示在图 3-4 中,正如您所见,Eclipse ADT 在我们的代码中没有发现任何错误,并且在右边的 outline 窗格中方便地总结了我们所有的实例变量、构造函数和方法。

9781430257462_Fig03-04.jpg

图 3-4。进入 Eclipse ADT 集成开发环境的 WorldGen 类的 Java 代码

现在我们已经编写了我们的 WorldGen 类,我们可以让其他类中的代码利用该类来创建 WorldGen (World)对象。

使用 WorldGen 类创建 WorldGen 对象

我们将(暂时)在 MainActivity 类中做这件事,只是为了向您展示它是如何完成的,然后在后面的章节中,我们将通过其他 Java 方法和类调用这段代码,可能会从一些新的 XML 用户界面元素中调用,比如菜单、按钮、文本字段等等。

单击 Eclipse central 编辑窗格中的 MainActivity.java 顶部选项卡,这样我们就可以切换到查看主要活动的 Java 代码。我们将使用 Java new( ) 方法添加一个对象声明,这允许我们创建新的 Java 对象。

我们将在我们的 onCreate( ) 方法中这样做,紧接在通过 super.onCreate( ) 方法调用创建我们的主活动的语句之后,以及在 setContentView( ) 方法调用之后,因为在我们可以做任何其他事情之前,我们需要已经创建了我们的活动,并且已经设置了它的内容视图。

使用构造函数方法调用创建 Java 对象的格式如下

<Declare Constructor Method> <Object Name> = new <Constructor Method Call>

所以,要创建一个 WorldGen 对象,我们声明它(WorldGen),然后命名它(earth),最后通过 new 关键字调用我们的构造函数方法,如图图 3-5 所示,像这样:

WorldGen earth = new WorldGen("Earth", 5973, 9.78);

9781430257462_Fig03-05.jpg

图 3-5。向我们的 MainActivity 类添加 Java 代码,通过我们的 WorldGen 类生成一个新的 World 对象

基本上,这一行代码应该是这样的:我想声明一个名为地球WorldGen 对象,它将是一个对象,它需要使用名为 WorldGen 的构造函数方法,传递给它三个参数**("地球",5973,9.78)** ,这些参数是在它的方法中定义的。

注意在图 3-5 中,当我们输入代码来创建新的地球 WorldGen 对象后,单词地球下面会加一条黄色波浪线。在 Eclipse 中,这是一个关于代码中那个单词的警告,为了让 Eclipse 告诉您它警告您什么,您只需将鼠标放在带下划线的单词上,就会弹出一个黄色对话框,告诉您 Eclipse 认为问题出在哪里。这也适用于该行代码左边的黄色警告图标。

在这种情况下,警告显示:没有使用局部变量 earth 的值,这是因为我们刚刚声明了它,甚至还没有时间使用我们的新 earth 对象。因此,在这种情况下,我们忽略警告,键入使用地球对象的第二行代码。

我们这样做是为了向您展示一个对象如何调用或调用它的方法,而且(只是一点点)我们这样做是为了去掉 Eclipse 中讨厌的黄色警告图标和波浪下划线。在我们创建了新的 earth WorldGen 对象之后,让我们使用这个 WorldGen 对象来调用一个 WorldGen 方法,以便将殖民地添加到我们的世界中。

为了从一个对象或在一个对象上调用一个方法,我们使用了一种叫做点符号的东西。最简单的形式是,这种符号采用以下格式:

<Object Name>.<Method Name>(Method Parameter List)

在这种情况下,我们将通过一行相当简单的 Java 代码向新的 WorldGen 对象 earth 添加一个新的 colony,如下所示:

earth.setPlanetColonies(1);

正如你在图 3-6 中看到的,这消除了地球对象声明中的 Eclipse 警告,因为该对象现在正在使用中,通过 setPlanetColonies()方法创建新的殖民地。咻!现在,我们的 IDE 中显示了干净的代码。真是松了一口气!

9781430257462_Fig03-06.jpg

图 3-6。在 Eclipse ADT 中对我们新创建的 earth WorldGen 对象调用 setPlanetColonies()方法

现在,让我们利用其他与设置属性相关的方法来添加其他对象配置设置,这些设置将为我们的新世界设置殖民地、军事基地、居民和士兵,并打开力场来保护地球免受外部攻击。

在设置行星殖民地的行后添加一行,并再次输入对象名称地球。请注意,Eclipse 用红色给该行加了下划线(因为它还没有被使用),并且一旦您按下句点字符来添加方法调用的点标记附件,Eclipse 将打开一个对话框,其中包含所有方法、变量以及您可以通过点标记从地球对象进行的其他调用。

这在图 3-7 中显示,是一个非常有用的功能,因为 Eclipse 现在在自己的用户界面助手对话框中引用自己的代码。

9781430257462_Fig03-07.jpg

图 3-7。使用 Eclipse 对象方法帮助器弹出来设置我们的其他新对象特征

在列表中找到 setPlanetMilitary( ) 方法,然后双击将其添加为下一个对象方法调用,然后在参数列表括号内输入一个 1 为新世界对象创建(添加)一个新的军事基地。

接下来,在那一行之后添加另一行,再次键入地球对象名称和句点字符,然后从出现的弹出列表中选择**setcolonymigration()**方法,并将移民设置为 1000 移民。

注意你也可以简单的输入**earth . setcolonymigration(1000);**您可以完全忽略 Eclipse 提供的弹出对话框,因为在您开始键入您想要通过 object dot 符号引用的方法名之后,它就消失了。

接下来,让我们引入 100 名士兵来管理我们之前添加到我们的世界对象中的军事基地。在下一行,输入:earth . setbase protection(100);或通过键入接地然后一个句号,并从对话框中选择 setBaseProtection 方法。

最后,在那之后再加一行,打开行星的力场,使用earth . setforcefieldon(); object 方法调用,这样我们新形成的星球现在就被保护在它的大气层外面了。

注意,最后一个方法调用不需要传递任何参数,所以括号是空的,不包含任何值。这是因为这种方法是一种开关,简单地通过调用它,我们就打开了地球保护力场的开关。

图 3-8 显示了 MainActivity 类中所有新的 Java 代码,用于创建新的 WorldGen 对象,以及在 Eclipse central editing 窗格中设置它的方法(无错误)。

9781430257462_Fig03-08.jpg

图 3-8。用 MainActivity.java 的 Java 代码创建一个新的名为 earth 的 WorldGen 对象并调用它的 set 方法

ADT Eclipse 内部的注释、警告和错误

注意在图 3-8 的中,我们已经注释了我们的 Java 代码,使用了双正斜杠字符序列来创建我们新的 WorldGen 对象。

这就是我们如何在 Java 中的每行代码后添加单行注释,正如你在我们最终的对象实例化代码的图 3-8 中看到的屏幕截图。

让你的注释文本尽可能的易读是很重要的,所以试着把你的注释排成一行,并且清楚的把它们和你的代码分开。让你的注释尽可能的简洁明了,这样他们会让其他程序员受益,他们以后会试着阅读你的代码,破译你在用它做什么。

同样重要的是要注意,Eclipse 将您的注释涂成绿色,以使它们在查看者面前更加突出。还要注意,为了可读性,Eclipse 还将其他关键的 Java 代码涂上了颜色,比如将 Java 关键字涂上紫色,变量名涂上蓝色,所有其他代码涂上黑色。

警告用黄色下划线标出,潜在的编译器错误用红色下划线标出。要查看 Eclipse 认为可能出错的地方,请将鼠标放在带下划线的文本上,或者在 Eclipse 代码编辑中心窗口主窗格中单击该行代码两侧的警告或错误图标。

现在我们已经了解了 Java 对象、类、方法和变量,让我们来看看最后一个 Java 构造,叫做接口,它允许我们定义供公共使用的 Java 类并公开定义它的方法。

为公众创建一个 Java 接口:IntWorldGen 接口

我想在本章介绍的最后一个 Java 概念是 Java 公共接口,尽管我们不会在 Hello World Android 应用中具体实现它。

Java 接口有很多规则,并且引入了一些我们在本章中还没有涉及到的新概念,比如抽象静态修饰符,所以最好最后讨论接口。此外,在我们为任何给定的类开发公共接口之前,我们将需要对我们所有的方法进行编码,因为我们现在已经完成了这一点,所以它一直工作得很好。你可能会想,接口是用来做什么的。

Java 接口为我们的 WorldGen 类做了什么

如果我们要将我们在本章中创建的 WorldGen Java 类发布到它自己的包中,供全世界的人用作他们自己的 World Generation Toolkit,并创建他们自己定制的 Hello World Planet Creation 应用,那么我们就要为他们定义 Java 公共接口

这个 Java 接口将精确地定义如何与我们的 WorldGen 类接口(使用什么方法以及如何利用它们)。我们将在本章的这一部分继续实际操作,向您展示这是如何完成的,但我们不会对我们在本章前面编写的代码实际执行(添加)这些更改。这是因为我们的 WorldGen 类是专门为我们自己的 Hello World Android 应用编写的,不会向公众发布。

如果您想对代码进行这些更改(将所有方法都变成公共的,就像构造函数一样),并实现这个接口,代码仍然可以工作,所以如果您愿意,您可以将此作为一个额外的练习。

在 Java 中,一个类的公共接口最常用于给你的类的用户一个关于它的所有方法的快照,以及这些方法操作(或使用)什么类型的数据值。这样做是为了让用户知道你的类方法做什么,以及通过什么样的变量数据类型来完成这些事情。Java 接口编码的一般格式如下:

<Access Control Modifier List> interface <Interface Name> { ... }

接口内声明的所有方法根据定义都是抽象,也就是说,它们不能直接使用,而必须被子类化才能使用,这就是抽象修饰符所表示的。

简而言之,抽象类是被编写(意味着)为子类的类,但不能用于直接创建对象。为了能够从一个抽象类中创建一个对象,你将该抽象类子类化,这使它成为一个具体的类(只要子类类在子类的类声明中没有在单词 class 之前用 abstract 修饰符声明)。如果我们把 WorldGen 抽象成这样:

public abstract class WorldGen { ... }

然后,为了创建 WorldGen 对象,我们必须从现在抽象的 WorldGen 类中继承一个具体的类,现在被设计为 WorldGen 模板:

public class WorldGenPlanets extends WorldGen { ... }

注意关键字扩展了,用于从 WorldGen 子类化 WorldGenPlanets。因为在 WorldGenPlanets 中没有抽象的修饰符,它是一个具体的类,只要它实现了所有的 WorldGen 超类方法,那么它就可以用来创建 WorldGenPlanet 对象。

因为在一个接口中声明的所有方法本质上都是抽象的,所以它们不需要使用 Java 抽象修饰符来声明。类似地,因为一个接口旨在(再一次,本质上)让向公众公开这些方法,所以 public 访问控制修饰符也是隐式假定的,因此也不必显式声明。

最后(没有双关的意思),所有在 Java 接口中声明的方法都被固有地声明为 final ,所以 Java final 修饰符也不必被显式包含。 final 修改器使某个东西,嗯,成为最终的,这样以后就不能修改了,有点像锁定功能。

定义为 final 的变量本质上是一个常数,并且只被初始化一次,然后从那时起就被固定了。任何修改代码中最终变量的尝试都会触发编译器错误(或者编译前 Eclipse 内部的错误通知)。最终变量与常量的不同之处在于,常量值在编译时是已知的,而最终变量的值在编译时可能是未知的。

为我们的 WorldGen 类创建一个 Java 接口

下面是一个简单的例子。假设我们已经用 final 修改器为 WorldGen 类集创建了 planetName、planetMass 和 planetGravity 实例变量。

如果我们以这种方式设置它,那么一旦这些变量被设置,通过我们的 WorldGen()构造函数方法的任何给定实例,这三个实例变量将被设置为 final 然而,它们不会在编译时被设置为常量值,而是在运行时通过我们的公共 WorldGen()构造函数方法由唯一的 WorldGen 对象的每次创建来设置。

声明为 final 的类不能被子类化;声明为 final 的 Java 类的例子是 java.lang.Stringjava.lang.System 。因此,如果我们将 WorldGen 类声明为:

public final class WorldGen { ... }

那么我们在本页前面所做的代码语句将不被允许:

public class WorldGenPlanets extends WorldGen { ... } // This will generate an error!

声明为 final 的方法不能在任何子类中被覆盖(也就是说,它的代码不能被更改、替换或增强),本质上锁定了该方法及其功能,因此以后不能被更改。

用 final 修饰符声明一个方法的原因是,它可能包含一些关键的功能,出于多种原因,包括代码稳定性、函数保留或一致性维护,这些功能不应该更改。不用说,final 修饰符在 Java 语言中确实是一个有用的工具,可以确保代码得到正确使用。在任何情况下,只要记住在 Java 接口内部声明的所有方法本质上都是公共的、抽象的和最终的。

当前存在的 WorldGen 的接口将被编码如下:

public interface IntWorldGen {
        void setPlanetColonies(int numColonies);
        int  getPlanetColonies();
        void setPlanetMilitary(int numBases);
        int  getPlanetMilitary();
        void turnForceFieldOn();
        void turnForceFieldOff();
        boolean getForceFieldState();
        void setColonyImmigration(int numColonists);
        long getColonyImmigration();
        void setBaseProtection(int numForces);
        int  getBaseProtection();
}

注意,我们在接口定义中不需要构造函数方法,只包括方法。您使用以下语法实现一个 Java 接口:

public class WorldGen implements IntWorldGen { ... }

implements 关键字将类的构造函数方法传递给新的接口实现,因此,在这种情况下,类名或接口名都可以用来创建新的对象,如下所示:

IntWorldGen earth = new IntWorldGen("Earth", 5793, 9.78);

和这样做是一样的:

WorldGen earth = new WorldGen("Earth", 5793, 9.78);

换句话说,一旦 WorldGen 实现了 IntWorldGen 接口,这两个对象实例化都将调用 WorldGen 构造函数方法。

摘要

在本章中,我们仔细研究了 Java 编程语言中一些更重要的面向对象编程(OOP)概念。同时,为了练习在 Hello_World 应用代码中实现这些概念,我们应用这些概念创建了 WorldGen World Generation 类。

我们可以使用这个 Java 类将在第二章中创建的 Hello_World Android 应用提升到一个新的水平,只要我们编写一些 XML 标记,在接下来的几章中添加一些很酷的屏幕布局、菜单、文本、按钮、用户界面设计、图形图像和动画。

我们首先查看了最高级别的 Java 构造,即 API应用编程接口,然后我们查看了 Java 以及它如何组织我们的项目代码。然后,我们看了 Android 中的包如何包含有用的 Android 类,我们可能希望将这些类导入并在我们自己的 Hello_World Android 应用以及其他应用中加以利用。

接下来,我们看了 Java 对象的概念,它是 OOP 的基础,也是 Java 编程语言中的核心编码结构。我们了解到 Java 对象对现实世界的对象进行建模,包括属性(实例变量)和功能(方法)。

下一个逻辑步骤是让我们看看如何使用 Java 创建 Java 对象,Java 类是允许我们定义实例变量和包含局部变量的方法的代码构造。

深入到类结构的下一层,我们看了 Java 方法,以及这些方法是如何创建的。我们写了十几个方法,所以我们现在有了 Hello_World Android 应用的世界生成工具包。我希望你不要以为我们只是要做普通的印刷“你好,世界!”在本书中的 Hello World 应用屏幕上,因为我们实际上要做的正好相反,创建有史以来最棒的 Hello World 示例应用实现!

在我们学习了一些 Java OOP 理论和行话之后,是时候启动 Eclipse ADT 并真正编写我们的 WorldGen 类了。我们学习了 Eclipse 如何在其 IDE 中为我们标记警告和错误,以及如何鼠标悬停和鼠标点击这些来找出 Eclipse 认为我们的代码有什么问题。我们还学习了当我们键入对象名并按下句点键时,如何让 Eclipse 收集我们的方法和变量,以及如何注释我们的代码以增强可读性。

最后,我们看了一下 Java 公共接口,以及如果我们决定为我们的任何类实现一个接口,它们是如何定义我们应该使用什么方法的,在本书的后面我们将对一些 Android 类这样做。

在下一章中,我们将开始为 Hello_World Android 应用构建屏幕布局、菜单和用户界面,但这一次我们将使用 XML 标记代码(大部分)来定义这些元素。

四、布局和活动:使用ViewGroup

既然我们已经在第三章中创建了 Java 代码,为我们的 Hello_World 应用生成了健壮的新世界(WorldGen),我们需要开始为我们的 Android 应用构建前端,我喜欢称之为用户界面设计

用户界面 (UI)设计、用户体验(UX)以及应用内容都是通过 Android 消费电子设备的主屏幕交付的,您的目标最终用户或客户正在使用该设备查看您的 Android 应用。用户体验(UX)是用户界面设计、可用性和内容感知影响的总和。

在这一章中,我们将仔细看看最底层,实际上是 Android 中任何屏幕设计的基础。这被称为 Android 布局容器,它是使用视图组类在 Android 中实现的。Android ViewGroup 类是 Android View 类的子类,后者本身是我们在第三章中了解到的 Java Object 类的子类。幸运的是,我们已经了解了 Java 类的层次结构。

我将再次尝试在这一章中无缝地融合两个目标;通过添加布局容器和菜单来再次增强我们的 Hello World 应用,并教你如何同时使用 XML 和所有关于 Android 视图视图组类概念来编写菜单和屏幕布局。

我们将在我们的 Hello_World 应用中定义一些不同类型的屏幕布局容器,并为它们提供基本的用户界面元素,稍后,我们将在本书的第二部分中用更高级的用户界面元素、图形、视频和动画来替换(升级)。我们还将学习如何创建 Android 活动,我们将使用它来保存我们的布局容器,并在 Hello_World 应用中定义逻辑区域。

Android 屏幕布局容器:ViewGroup 类

在 Android 中,屏幕布局是通过 Android ViewGroup 类创建、定义和组织的,该类是从更一般化的 View 类继承而来的。View 类必须通过大家熟悉的 **import android.view.View 导入到每一个 Android 应用中;**声明。

因为 Android 视图类以各种方式管理我们的屏幕界面,所以它最终有大量的子类,而大多数视图子类本身有更专门的子类,正如你将在本章中看到的,以及在下一章涵盖用户界面设计中看到的,一般来说,贯穿本书的其余部分。

不用说,视图在 Android 中很重要,因为它们提供了你的应用和最终用户之间的接口。Android View 包用于在新的 Android 应用项目对话框中创建的 bootstrap (basic) Android 应用,因为要使用应用的屏幕,您必须导入 View 类才能做到这一点。

Android View 类有大量专门的子类,其中许多我们会在第五章中详细讨论。本章致力于一个非常特殊的视图子类,叫做视图组,它允许以小部件子类(用户界面元素)的形式无缝地组织视图子类。

ViewGroupView的子类,因为 Android View类提供了那些顶级的屏幕管理特征(大小、尺寸、方向和类似的屏幕属性)以及功能(事件处理、焦点等)。)我们将在第五章中详细介绍。

ViewGroup子类增加了全局屏幕布局属性和方法,允许开发人员定义和微调屏幕布局组织特征和顶级功能。

就像 Android View 类为其ViewGroup子类提供更高级别的属性和功能一样,ViewGroup base 类为其自身的子类提供更高级别的屏幕布局参数属性和屏幕布局创建功能。

我在这里提到这个的原因是因为在 Android 中没有直接使用ViewGroup类来实现任何特定的布局容器;因此,它可以被定义或归类为它的许多子类中的一个基本类。

所以,请记住,Android 开发人员目前可以使用的所有不同类型的屏幕布局容器类来创建用户界面设计,实际上是 Android ViewGroup基类的子类。

Android 视图组子类:布局容器类型

Android 提供了几种主流的布局容器类型作为 ViewGroup 类的子类。这些类是你将在大多数项目中使用的,也是我们将在本书中涉及的。

这些 ViewGroup 子类被命名为: RelativeLayout (默认布局类型,在新的 Android 应用项目对话框中创建)、 FrameLayout (用于单项布局)和 LinearLayout (用于需要符合行或列格式的用户界面元素,如内嵌按钮条和自顶向下列表)。

还有一些其他的布局容器类型被弃用了,我们不会讨论这些,因为它们已经停止使用了。弃用意味着停止使用,但仍支持(但不推荐)使用,以便使用此弃用代码的旧代码仍能运行。Android 中被弃用的布局容器和被弃用时的 API 等级包括 AbsoluteLayout (等级 3)和 SlidingDrawer (等级 17)。

还有一些布局容器类型本质上与 deprecated 正好相反,也就是说,它们太新了(API 级别 13 和更高),以至于 Google 还没有完成它们的代码实现,如果使用它们,当所有的功能最终就绪时,您可能需要在以后更改代码。此外,它们只能在 API 级别 13 到 17 下工作,不支持 API 级别 3 到 12,而传统的消费电子产品仍然支持 API 级别 3 到 12。在本书中,我们想要关注的是适用于所有 Android 设备的布局容器。

API 级(蜂巢)及以后的布局容器有网格布局、 **ViewPager、**和 PagerTitleStrip ,这些我们就不赘述了。

注意,我们也不讨论 FragmentBreadCrumbs 布局容器,因为它的复杂性超出了学习 Android 应用开发的入门书籍的范围。

我们看到的第一个布局容器是最常用的容器之一,也是 Android 操作系统的默认容器: RelativeLayout 。因为RelativeLayout已经在您的引导 Hello_World activity_main.xml 文件中设置好了,我们将继续向您展示如何正确使用它。

相对布局定位:Android RelativeLayout 类

我们将从 RelativeLayout 类开始,因为这是 Eclipse ADT 在我们新的 Android 应用项目系列对话框中为我们设置的默认布局容器。我们将使用它,并首先了解 RelativeLayouts,因为它们是最常用的。

RelativeLayout容器被恰当地命名,因为它使用相对定位来排列用户界面元素(UI 窗口小部件,使用 Android View类对其进行子类化,我们将在下一章中学习)。

在本章的下一节中,当我们开始使用 Android XML 标记语言编写 Hello_World 应用启动屏幕用户界面元素时,您将看到如何创建相对布局,用参数填充,然后进行微调。

我们将使用当前的 主活动屏幕活动作为我们的启动屏幕。因为我们已经定义了一个“默认”或初始地球世界,我们将在我们的应用主屏幕上使用它来向我们的最终用户显示他们当前所在的位置地球。这样,我们就不用重写任何代码了!

我们还将向您展示如何定义菜单,以便您可以调用其他屏幕(活动)定义。我们在这些活动中使用不同类型的屏幕布局容器,以便您可以了解每种容器是如何实现的。我们在本章中介绍菜单,因为菜单代码已经在第二章中写好了,所以尽可能早地实现我们的菜单是合理的,这样你就可以学习如何为你的活动屏幕实现菜单。另外,菜单也是 UI 设计的一部分,对吧?

创建启动屏幕:通过 XML 定义我们的 relative layout

我们定义的第一个屏幕(活动)布局容器是我们的 Hello World 应用启动屏幕,它是在第二章中定义的。Java 代码位于 MainActivity.java 的中,XML 标记位于的 activity_main.xml** 中,目前它是一个带有 Hello World 的 RelativeLayout 容器!里面有短信。**

我们希望将这个当前的启动屏幕转化为一个信息图表,显示我们的应用最终用户当前所处世界的当前属性。我们使用一些 Java 代码和 XML 标记更改(相当小的更改)。当应用首次启动时,这是我们在第三章中定义的地球物体。我们将让我们的用户在世界之间旅行,所以我们必须从一开始就让这个屏幕访问变量内容(而不是固定的文本值),这让它变得有点困难。让我们设计我们的屏幕输出如下:

Planet Name:            Earth           <planetName instance variable>
Planet Mass:            5,973 YG        <planetMass instance variable>
Planet Gravity:         9.78 m/s        <planetGravity instance variable>
Planet Colonies:        1               <planetColonies instance variable>
Planet Population:      1,000           <planetPopulation instance variable>
Planet Military:        100             <planetMilitary instance variable>
Planet Bases:           1               <planetBases instance variable>
Planet Forcefield:      On              <getForceFieldState() method call>

这在我们的相对布局容器中转化为八个文本字段(在左边),包含八个字符串常量和八个右边的文本字段,它们访问我们的 WorldGen 对象方法和变量,当我们的用户旅行到另一个世界时,可以通过 Java 代码设置。

尽管我们将在下一章详细介绍用户界面元素,但我们至少要介绍一个视图子类(TextView)来创建这个当前世界信息启动屏幕。所以,让我们点击 Eclipse 快速启动图标,开始吧!

Eclipse 打开我们的 Hello_World 应用,正如我们在第二章和第三章中对它的配置一样。顶部应该有已经为 activity_main.xml (res/layout 文件夹)、activity_main.xml (res/menu 文件夹)、strings.xml (res/values 文件夹)、MainActivity.java(src/chapter . two . hello _ world 文件夹)和 WorldGen.java(src/chapter . two . hello _ world 文件夹)打开的编辑选项卡。让我们从单击 strings.xml edit 选项卡开始。

为启动屏幕创建字符串常量

让我们先添加我们的启动屏幕信息文本标签常量,因为我们的 RelativeLayout 容器中的 TextView 小部件将访问它们。正如您所看到的,在这个 XML 文件中已经为我们的应用名称(Hello_World)和 Hello_World 问候消息定义了字符串常量,还为一个菜单标签(设置)定义了字符串常量,我们稍后将对其进行一些更改。

单击 strings.xml 的编辑选项卡,并为我们在本节前面定义的八个世界信息字段标签添加 < string > XML 标签。XML 标签应该看起来像这样,也显示在图 4-1 : 中

<string name="planet_name_label">Planet Name: </string>
<string name="planet_mass_label">Planet Mass: </string>
<string name="planet_gravity_label">Planet Gravity: </string>
<string name="planet_colonies_label">Planet Colonies: </string>
<string name="planet_population_label">Planet Population: </string>
<string name="planet_military_label">Planet Military: </string>
<string name="planet_bases_label">Planet Bases: </string>
<string name="planet_forcefield_label">Planet Forcefield: </string>

9781430257462_Fig04-01.jpg

图 4-1。在 Eclipse 的 strings.xml 文件中添加我们的八个启动屏幕文本常量

请注意,我们在每个分号后添加了一个空格,这样我们稍后添加的变量数据就不会接触到我们的标签文本常量。作为程序员,我们必须总是提前考虑像这样的 UX 问题。

通过向我们的启动屏幕用户界面添加文本

现在点击包含了 xml 容器的 activity_main.xml 标签,图 4-1 中最左边的编辑标签。我们不需要(或不想)将这些新的 TextView 元素垂直或水平居中,所以我们想做的第一件事是删除这两个 XML 参数。

接下来,让我们向第一个 TextView UI 元素添加一个 android:id 参数,就在开始的 < TextView > 标签之后。这样,一旦我们复制并粘贴了所有的 TextView 标签,我们就可以根据我们如何配置第一个标签,通过名称来识别我们的 RelativeLayout 中的每个 TextView 标签。

这个 ID 还被用来从 Java 以及我们的 XML 标记中引用每个 UI 元素 ,这是使用我们现在熟悉的 android:id XML 参数来完成的。参数是这样写的:

android:id="@+id/textView1"

最后,更改文本视图中的最后一个参数, android:text 指向我们之前在 strings.xml 文件中创建的**@ string/planet _ name _ label**。完成的 TextView UI 元素 XML 标记如图图 4-2 所示。

9781430257462_Fig04-02.jpg

图 4-2。在 Eclipse 中添加 TextView XML 标签,并通过弹出对话框配置相关布局参数

因为我们的活动屏幕上只有一个 UI 元素,这里仍然没有相对的布局定位,所以让我们复制并粘贴第一个 TextView UI 元素到它本身的下面,这样我们就有了两个,然后可以探索它们相对于彼此的定位。

通过编辑 android:id 参数,将第二个标签命名为 textView2 ,如图图 4-2 所示,然后记得同时更改标签的 android:text 参数,以指向我们之前在 values 文件夹的 strings.xml 文件中定义的 planet_mass_label 字符串常量。

接下来,我们通过在 android:id 参数下添加一行并键入单词 android 来添加我们的相对定位参数。注意,在你按下参数名的 android 部分之后的冒号字符之后,在参数名的布局部分之前,你触发了一个 Eclipse 参数助手对话框,如图图 4-2 所示。

XML 参数选择器助手对话框总是弹出参数建议,就像我们在定义 Java 对象时按下句点键后在第二章中观察到的一样。

在你按下冒号键之后,继续输入单词布局,注意,当你输入的时候,Eclipse 会根据它认为你正在寻找的内容,提炼弹出帮助器的内容,再次显示在图 4-2 中。

在输入完 android:layout 之后,你就列出了所有可以用于 relative layout 容器的相关布局参数。

正如你在图 4-2 中看到的,大约有三打(显示了一打,因为滚动条是高度跨度的三分之一,我估计是三倍),你需要选择列表中的第五个。

双击 android:layout_below 参数以选择它的用法(因为我们希望我们的 TextView UI 元素一个在另一个下面)。一旦这个相对布局参数被添加到 Eclipse XML 编辑窗格中,在 helper 实用程序提供给您的两个引号字符内键入 @+id/textView1 引用,这是对直接位于它上面的第一个 TextView UI 元素的引用。

注意,例如,如果你在一个 LinearLayout 容器中,这个参数弹出帮助对话框将包含与安卓布局容器的 LinearLayout 类型兼容的参数。

接下来,我们将使用第一个 TextView XML 标记创建的第二个 TextView XML 构造复制并粘贴六次,这样我们就不必再键入六次所有的 TextView 标记及其参数。

对于六个复制的 TextView 标签中的每一个,让我们编辑每个复制的 TextView 标签的' android:text 参数中的 @string 变量,以便它们与最后六个< string >标签常量名称相匹配,这些名称是我们之前在 values 文件夹中的 strings.xml 文件中定义的。

最后,让我们为六个复制的 TextView 标签中的每一个编辑 android:layout_below 参数,这样每一个都指向,或者说引用,TextView UI 元素的 android:id 参数,它直接位于每一个标签之上。

Hello_World 应用启动屏幕的文本标签常量的八个 XML 标签现在定义在我们的activity _ mainrelative layout XML 容器中,应该看起来像图 4-3 中所示的屏幕。

9781430257462_Fig04-03.jpg

图 4-3。我们配置了相对布局(layout_below)参数的八个基本 TextView XML 标签

注意,有两种不同的方法来关闭 XML 标签。一种方法是在标签参数后用一个 / > 符号来结束每个 TextView 标签。这是关闭没有任何其他标签嵌套在其中的标签的方法。

另一种在 XML 标记内嵌套有其他标记的情况下关闭 XML 标记的方法是,只使用一个 > 符号来关闭开始标记,然后在该标记内的任何嵌套项后让标记名以/ >符号结尾。我们这里的 < RelativeLayout > 标签就是这种情况。

在图 4-3 中,我们可以看到这两种不同的标签关闭方法,我们当前的相对布局标签和嵌套在其中的文本视图标签。

现在让我们编译并运行我们的 Hello_World Android 应用,看看我们的启动屏幕到目前为止是什么样子。确保你写的所有代码都保存好了(你可以在任何标签页使用 CTRL-S 随时保存,然后你可以在左边的包浏览器窗格中右键点击项目文件夹,然后选择运行为 Android 应用菜单选项。

正如你在图 4-4 中看到的,我们的启动屏幕的文本标签彼此完美地排列在一起,所以我们的相对布局参数工作良好。为了完善我们的用户体验,我们唯一需要做的就是将我们的八个文本标签向右移动一点,这样它们就不会碰到用户屏幕的左边缘。

9781430257462_Fig04-04.jpg

图 4-4。在 Nexus S 模拟器中运行我们的 RelativeLayout,看看相对定位是如何工作的

我们将通过使用 RelativeLayout 容器左边距参数Android:layout _ margin left来实现这一点。这要求我们为八个 TextView 标记中的每一个添加一行 XML 标记,如下所示:

android:layout_marginLeft="5dip"

这将我们的文本常量标签向右移动五个设备独立像素 ( 倾斜DP ),为我们的新启动屏幕创建一个直的左边距。将这一行 XML 标记添加到每个 TextView,就在 android:id 参数之后,然后使用 Run As Android App 命令检查结果。

通过向我们的启动屏幕用户界面添加数据

现在我们已经准备好添加 TextView UI 元素,它将保存我们的 WorldGen 对象的实际数据值。我们将使用一些新的相对布局参数,类似于我们刚刚用来完成这个屏幕的用户界面设计的左半部分。

让我们再次采用另一种快捷方式,复制第一个 textView 标记,将其 ID 从 textView1 重命名为 dataView1 ,并进行一些其他更改,以创建我们的对象数据变量 TextView 用户界面元素标记,如下所示:

<TextView
        android:id="@+id/dataView1"
        android:layout_toRightOf="@+id/textView1"
        android:layout_marginLeft="36dip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/planet_name_label" />

我们添加的第一个东西是一个 android:layout_toRightOf 参数,它告诉我们这个将保存我们的星球名称变量数据值的第一个 TextView UI 元素被放置在 toRightOf (在我们的相对布局容器中的第一个星球名称标签常量的右边)。

我们需要修改的第二件事是Android:layout _ margin left参数,它用于将变量数据推出,远离标签常量。现在,我保留了 android:text 参数(我们稍后将在工作过程中删除它),这样我们可以在屏幕中间将变量数据排成一条直线,这样看起来更专业。

让我们通过将marginLeft设置为 36dip 来推出可变数据文本(现在使用行星名称“虚拟”文本),以便它比屏幕左侧的最长标签常数(行星数量)稍微远一点。这为我们排列其他可变数据文本 UI 元素提供了一个基线。XML 代码如图 4-5 所示。

9781430257462_Fig04-05.jpg

图 4-5。使用 android:layout_toRightOf 参数添加变量数据 TextView

现在,我将向您展示我是如何精确地获得这个 36°倾角设置值的,而不是在我优化该参数时连续多次使用作为 Android 应用运行的(仿真器),因为这个工作过程可能非常耗时!

Eclipse XML 标记编辑窗格中有一个新特性叫做图形布局编辑器(我经常称之为 GLE ,简称,可以通过一个小标签在 XML 编辑窗格的左下方访问,如图 4-6 中用红色圈出的所示。

9781430257462_Fig04-06.jpg

图 4-6。使用 Eclipse 图形化布局编辑器来预览我们的相对布局参数设置

单击这个 GLE 选项卡“呈现”您在模拟器中编写的 XML 代码,当您通过 MainActivity Java 代码运行该 UI 设计时,模拟器将向您显示这些代码。注意,这个 GLE 也可以用来为您编写 XML 代码,使用拖放功能,您可以在它的周围看到。因为我们都是程序员,所以我将严格从代码编写的角度来看这本书,并主要使用这个 GLE 特性作为渲染设计预览的捷径,以节省我们 UI 设计过程中及时的仿真器启动周期。

同样,让我们复制第二个 textView 标签,将其 ID 从 textView2 重命名为 dataView2 ,并做一些其他更改来创建我们的下一个对象数据变量 TextView 用户界面元素标签,如下:

<TextView
        android:id="@+id/dataView2"
        android:layout_toRightOf="@+id/textView2"
        android:layout_alignStart="@+id/dataView1"
        android:layout_alignBelow="@+id/dataView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/planet_mass_label" />

我们将 ID 重命名为 dataView2,确保它是 textView2 的to right,将 alignBelow 参数设置为低于 dataView1,还将 marginLeft 参数替换为Android:layout _ align start参数。

我们使用的这个新的相对布局参数对齐 UI 元素的起始(像素)位置,我们将它设置为引用我们刚刚创建的 dataView1,以便 dataView1 和 dataView2 完美地对齐。

现在,我们将 android:text 引用设置为我们在 textView2 标签中使用的相同的 planet mass 字符串,尽管稍后我们可以删除它,因为最终我们的 Java 代码将设置这个值,并且我们将不需要它来检查对齐(这就是为什么我们现在将它留在这里)。

一旦我们做了这些改变,如图 4-7 所示,我们可以使用 dataView2 作为模板,复制并稍作修改,创建 dataViews 3 到 8。

9781430257462_Fig04-07.jpg

图 4-7。使用 android:layout_alignStart 参数将 dataView2 与 dataView1 的左侧对齐

在我们复制并粘贴了 dataView3 到 dataView8 的 TextView 标签后,我们可以点击屏幕底部的图形布局编辑器选项卡,并看到我们的虚拟文本变量完全对齐,如图 4-8 中的所示。

9781430257462_Fig04-08.jpg

图 4-8。使用 layout_alignStart 参数在图形布局视图中排列的虚拟数据文本变量

注意,当我们复制它时,唯一可以灵活改变其值的相对布局参数是Android:layout _ align start参数。它可以被设置为引用 dataView1 或它上面的数据视图。我在它上面使用了 dataView,因为从我复制的前一个 dataView 标记的每个副本中为每个数字加 1 更容易。这就是我复制这些数据视图标签的工作流程。

使用 Java 将数据写入我们的启动屏幕 UI

现在我们需要让我们的 Java 代码用实际的对象变量数据值替换这些虚拟实例变量(这将在运行时完成)。这要求我们在我们的MainActivity类中编写一些方法。

我们编写第一个方法将用于巩固我们的onCreate()方法,通过把我们放在那里的所有对象创建代码,回到第二章的,并创建一个 setStartUpWorldValues( ) 方法来以有序的方式设置我们的初始(默认)世界对象和位置的值。

因为我们也在编写一个 setStartUpScreenText( ) 方法来访问我们的earth WorldGen对象,我们需要将创建我们的WorldGen对象的代码行移到我们的MainActivity类的顶部,如图图 4-9 所示,这样该类中的所有方法都可以访问它。这一行 Java 代码如下所示:

WorldGen earth = new WorldGen("Earth", 5973, 9.78);

9781430257462_Fig04-09.jpg

图 4-9。将 WorldGen 对象创建和配置代码重写为 setStartUpWorldValues()方法

用实例变量数据设置填充我们的earth WorldGen对象的其余 WorldGen方法调用现在放在我们的保护的 void setStartUpWorldValues( ) 方法的花括号内,如图 4-9 所示。这个方法被保护,这样这个类(和子类)中的其他方法,比如onCreate()就可以访问(调用)它。它也被声明为 void ,因为它执行一个不返回值的任务。还要注意,我们已经将注释与代码一起复制并对齐了。

现在是时候编写我们的第二个 setStartUpScreenText( ) 方法了,该方法将使用来自名为 earthWorldGen对象的数据填充 dataView TextView UI 元素。对于每个 dataView TextView 对象,这需要两行 Java 代码;一个用于创建、命名和引用 TextView UI 元素,另一个用于将其 android:text 参数值设置为每个 earth WorldGen 对象实例变量数据字段的值。

为了声明和命名我们的第一个 TextView 对象,我们使用这行代码:

TextView planetNameValue = (TextView)findViewById(R.id.dataView1);

这将对象声明为 TextView 类型,将其命名,并引用我们在 activity_main.xml 文件中设计的 dataView1 标记。

请注意图 4-10 中的,当我们键入文本视图对象类型时,Eclipse 使用红色波浪下划线,当我们将鼠标悬停在下划线对象类型上以了解原因时,Eclipse 通知我们文本视图无法解析为类型,并给我们一些潜在的解决方案,其中最明显的是第一个导入文本视图,因为我们从第二章中知道,在我们自己的代码中使用对象类之前,我们必须导入它。

9781430257462_Fig04-10.jpg

图 4-10。编码 setStartUpScreenText()方法,添加 dataView TextView 及其 import 语句

所以点击**Import TextView(Android . widget package)**选项,让 Eclipse 为您编写我们的 Import 语句,正如您将在图 4-11 中看到的,它现在已经就绪,可以使用了。

9781430257462_Fig04-11.jpg

图 4-11。使用 Java。setText()方法调用来为 dataView1 设置我们的 planetNameValue TextView 对象

我们需要编写的第二行代码获取我们刚刚声明的名为 planetNameValue 的 TextView 对象,并使用它来调用 TextView 类的一个用于设置文本值的方法。毫无疑问,这个方法被称为**【setText()】方法。您会注意到,在您键入 planetNameValue 对象名称,并键入句点字符后,Eclipse 将弹出其对象方法选择帮助器对话框,如图 4-11 所示。向下滚动到列出的setText(char sequence text)**方法,双击它将对该方法的点调用添加到您的对象中。

在圆括号内输入对 earth.planetName 对象和实例变量数据值的引用,用于方法调用,如图图 4-12 所示。现在让我们为行星质量数据编写第二两行代码。

9781430257462_Fig04-12.jpg

图 4-12。【setStartUpScreenText()的 Java 代码,用地球对象数据填充 dataView UI 元素

复制 TextView planetNameValue 行代码,将 planetNameValue 改为 planetMassValue ,然后在 findViewById( ) 方法调用中引用 dataView2 而不是 dataView1。然后复制 planetNameValue.setText()代码行,并更改 planetNameValue 对象名,以匹配在前面一行 Java 代码中创建的 planetMassValue 对象名。

因为 planetMass 是一个整数数据值,我们将不得不在我们的中嵌套一个方法。setText( ) 将整数值转换成字符串值的方法。这是通过完成的。字符串类的 valueOf( ) 方法,由**嵌套调用****String . value of()**方法调用如下:

planetMassValue.setText(String.valueOf(earth.planetMass));

这一行 Java 代码嵌套了两个方法调用,将**String . value of(earth . planet mass)方法调用的返回值(将整数值转换为字符串值)传递给planet mass value . settext()**方法调用(需要一个字符串值作为输入),所有这些都在一个非常紧凑(嵌套)的代码语句中。

接下来的六行与这两行非常相似,所以让我们走编码者的捷径,复制最后两行代码六次,并相应地替换我们的 dataView 和 planetVariableValue 命名约定。所有这些艰巨的 Java 编码工作的结果如图 4-12 所示。

现在让我们在 Nexus S 模拟器中运行我们的 Hello_World Android 应用,看看这个启动屏幕结出了我们的劳动果实。右键单击项目文件夹,并选择 Run As Android Application ,您将看到我们的 XML 和 Java 编码工作已经生成了一个完美的应用 UI 屏幕,它为我们之前创建的 earth WorldGen 对象创建了一个数据信息屏幕,并将作为我们 Hello_World 应用的初始主世界。如图 4-13 中的所示。

9781430257462_Fig04-13.jpg

图 4-13。使用填充了对象数据的 dataView TextView UI 元素运行 Hello_World 应用

接下来,让我们在主页(启动)屏幕的底部添加一个菜单系统!

向我们的活动添加菜单:菜单展开器和菜单 XML

我们需要做的第一件事是定义我们的启动屏幕菜单。Android 中的菜单通常只有五个或更少的条目,所以让我们挑选五个主要功能,我们需要在本章的后面定义布局屏幕(活动)。毕竟这是版面设计章节。

我们的 Hello_World 行星生成器需要有屏幕,允许其用户选择一个新世界,设置其属性,访问该行星(和平时期),攻击该行星(战争时期),并返回到主屏幕(启动屏幕),我们称之为显示主行星,以防用户离开地球,并前往他们创建的其他行星之一。

因此,逻辑启动(主页)屏幕菜单选择,以及当菜单项被选择时它们将调用的 Java 活动、XML 标记文件名和布局容器类型如下:

Add a New Planet       Call NewActivity.java, activity_new.xml             RelativeLayout
Configure Planet       Call ConfigActivity.java, activity_config.xml       LinearLayout
Travel to Planet       Call TravelActivity.java, activity_travel.xml       FrameLayout
Attack on Planet       Call AttackActivity.java, activity_attack.xml       LinearLayout
Show Home Planet       Stay in MainActivity.java, activity_main.xml        RelativeLayout

请注意,我们已经将菜单标签设计为均匀间隔(文本排列整齐)。这是为了让我们的菜单看起来尽可能吸引我们的终端用户,增强我们应用的用户体验或 UX。

为了向我们的主活动屏幕添加菜单项,我们将使用 XML 标记在名为 activity_main.xml 的文件中定义我们的菜单项,该文件位于我们的 res (resources)文件夹中的菜单文件夹中。但是,我们已经在布局文件夹中有一个 activity_main.xml 文件,你正在聪明地思考。这是正确的;然而,该文件在布局文件夹中,因此是与同样在菜单文件夹中的 activity_main.xml 文件不同的文件,尽管它具有完全相同的文件名。

每个布局容器 XML 定义和每个活动屏幕的菜单 XML 定义应该具有相同的文件名,如果您稍微考虑一下,这确实非常符合逻辑,因为您的应用(如果是高级应用)中的每个屏幕(活动)都将定义复杂的用户界面或内容元素(布局 XML),以及为每个活动(功能应用区域和屏幕)定义的菜单选择(菜单 XML)。

请注意,我正在交换这些屏幕/活动术语,至少是一小会儿,这样你就会习惯 Android 的行话。在我们向您展示如何为我们的菜单将要调用的这些屏幕编写单独的活动类之前,让我们修改新的 Android 应用项目系列对话框为我们创建的当前 activity_main.xml 文件,以便它包含我们的五个菜单标签,而不仅仅是一个设置标签。

从我们在第二章中的工作来看,您仍然应该在 Eclipse IDE 中打开 activity_main.xml 的菜单文件夹版本,如果它没有在 IDE 中打开,只需打开菜单文件夹并右键单击 activity_main.xml 文件,然后从上下文相关菜单中选择打开选项。然后点击 XML 编辑选项卡,再复制四次<条目>标签,创建我们五个条目的菜单。在我们复制现有的<项目>标签之前,让我们先编辑它,使它与我们之前设计的第一个菜单项匹配。

android:id 从 menu_settings 更改为 menu_add ,将 android:title 更改为 menu_add_planet ,然后在第一个标签下复制< item >标签四次。将 menu_add 的 android:id 参数分别更改为:menu_config、menu_travel、menu_attack 和 menu_home。

然后将Android:orderin category值分别改为:200、300、400、500,将 android:title 参数分别改为:menu_config_planet、menu_travel_planet、menu_attack_planet、menu_home_planet。

因此,每个标签应该具有相同的基本格式,如下所示:

<item android:id="@+id/menu_function"
        android:orderInCategory="Number Value for Order in Menu"
        android:showAsAction="never"
        android:title="@string/menu_string_constant" />

该工作过程的结果显示在图 4-14 中的最终 XML 菜单标记中。

9781430257462_Fig04-14.jpg

图 4-14。将我们的五个菜单项添加到菜单文件夹中现有的 activity_main.xml 菜单定义文件中

现在我们需要将菜单标签文本常量添加到我们的 strings.xml 文件中,所以接下来单击 Eclipse 顶部的 strings.xml 选项卡,并编辑已经存在的用于名为 menu_settings 的的标签,将其转换为标签值为 Add a New Planet 的menu _ Add _ Planetstring>标签。

一旦你完成了这些,复制标签四次,编辑标签来创建四个新的 menu_config_planet,menu_travel_planet,menu_attack_planet 和 menu_home_planet 字符串常量,如图图 4-15 所示。每个<字符串>标签应该遵循相同的基本格式:

<string name="menu_add_planet">Add a New Planet</string>

9781430257462_Fig04-15.jpg

图 4-15。将我们的五个菜单标签字符串常量添加到 values 文件夹中的 strings.xml 文件中

我们不需要编写 Menu Inflater 代码来创建菜单,因为新的 Android 应用项目助手已经为我们完成了这项工作,但是,因为我们在这里使用它来创建我们的菜单,所以现在让我们更仔细地看看它,并把它处理好。以下是菜单增压泵代码:

public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
}

onCreateOptionsMenu( ) 方法是 Android Activity 类的一部分,它用于为任何给定的活动创建选项菜单。在这个特例中,它是我们的 android.app.ActivityMainActivity 子类,它被导入到我们的 MainActivity.java 文件的顶部。

该方法将一个名为 Menu 的 Menu 对象传递给该方法,在该方法中,它通过一个 inflate( ) 方法填充了您的 menu XML 参数,该方法通过 R.menu.activity_main 方法中的第一个(inflate from)参数引用您的**\ resource \ Menu \ activity _ main . XML**文件,然后将该数据膨胀到第二个(inflate to object)参数中,该参数是声明并传递给 onCreateOptionsMenu()方法的 menu 对象。

getMenuInflater( ) 方法调用 inflate()方法,并使用它来填充活动的 MenuInflater 对象。 MenuInflater 类是 android.view 包(Android . view . MenuInflater)的一个成员,它使用那些 <菜单> 和<项目> 标签及其参数,获取您的菜单 XML 定义和实例化膨胀的菜单对象。

一旦 getMenuInflater()。inflate( ) 过程已经完成,没有任何失败, onCreateOptionsMenu( ) 方法退出,并返回一个 true 值,表示菜单资源已经被正确实现。

我们现在可以右键单击我们的项目文件夹,并选择 Run As Android Application 命令来编译和运行我们的 Java 和 XML 代码。让我们来看看我们的菜单在模拟器中的效果,如图 4-16 所示。

9781430257462_Fig04-16.jpg

图 4-16。带有功能菜单的主活动启动屏幕

在我们可以在 Java 代码中实际实现这些菜单选项之前,我们需要为每个菜单选项创建布局容器(通过 XML 标记)和活动(通过 Java 代码)。这是因为选择这些菜单项中的每一个都会将应用切换到这些活动中的每一个。

因此,让我们为前四个菜单选项创建四个新的 Activity Java 类,每个类都有自己的自定义布局容器 XML 定义,如图 4-16 所示,包含了我们的 Hello_World Android 应用的主要功能区域。

这些新的活动及其布局容器为我们提供了大量的应用功能屏幕,在本书的接下来几章中,我们将学习 Android 中的事件、意图、UI 小部件、图形设计和动画。

定义添加新星球屏幕:创建 Android 活动

我们需要做的第一件事是为我们的 Add a New Planet 菜单项创建一个 NewPlanet 类,所以右击你的 Hello_World 项目文件夹并选择 New image Class 菜单项。我们将使用与我们在第二章中创建 WorldGen 类时相同的工作流程,除了这一次,我们将子类化 android.app.Activity 类,因为我们正在创建一个活动,而不是一个世界对象生成器。

这两种类型的类的主要区别在于,Activity 类没有构造函数方法,而生成对象的类有。这是因为活动不是在运行时生成的,需要在 AndroidManifest.xml 文件中定义。

新建 Java 类对话框中点击浏览。。。按钮位于区旁边。选择 chapter.two.hello_world 包,然后在 Name: 字段中输入 NewPlanet 来命名我们的新活动类。这个活动类是以它将允许我们的最终用户在一个新的星球上添加什么来命名的。

接下来点击浏览。。。旁边的按钮超类字段,输入活动(只输入行为会得到相同的结果)将所有与活动相关的类带入选择区域。

选择 Activity - android.app 包选项,然后点击 OK 按钮。保留对话框中的其他默认设置,点击完成按钮。瞧,您的NewPlanet.java类被创建并在 Eclipse 中央编辑窗格区域内打开进行编辑。

接下来,我们添加一个 onCreate( ) 方法,最简单的方法是单击新类中的空白行(在两个花括号之间)来选择它(它变成浅蓝色)并按住 Control (Ctrl)键,同时按下空格键、,这是调出 Eclipse ADT 方法选择器助手对话框所需的击键序列。

在对话框中向下滚动一半,找到onCreate(Bundle saveInstanceState):void方法,如图图 4-17 所示,双击该方法,将需要的 onCreate()方法添加到我们的 NewPlanet (class) Activity 子类中。您创建的每个活动都需要实现一个 onCreate()方法,以便它可以在系统内存中创建活动。完成后,您可以定义一个区域来查看您的应用内容,这是我们接下来要做的。

9781430257462_Fig04-17.jpg

图 4-17。ctrl-空格键击键序列调用方法选择器助手对话框

super.onCreate( ) 方法调用之后,我们需要添加一行调用 setContentView( ) 方法的代码,类似于我们的 MainActivity.java 文件中的代码。事实上,您可以采用程序员的快捷方式,剪切并粘贴那行代码,然后修改它以引用我们接下来要创建的 activity_add.xml 文件。代码应如下所示:

setContentView(R.layout.activity_add);

请注意,当您这样做时,Eclipse 使用红色波浪下划线来标记 activity_add 引用,如图图 4-18 所示,我们已经知道这是因为引用的文件还不存在,所以我们现在忽略这个错误,因为我们将在这个活动创建工作流程的下一步创建这个布局 XML 文件。

9781430257462_Fig04-18.jpg

图 4-18。将 setContentView()方法调用和引用添加到尚未创建的 activity_add.xml 文件

在包浏览器中再次右键单击 Hello_World 项目文件夹,然后选择 New image Android XML File 菜单选项。从下拉列表中选择布局 XML 类型(如果还没有这样设置的话)并指定 Hello_World 项目。接下来添加 activity_add 文件名(仅第一部分,对话框添加。xml extension for you ),从对话框中间的选择区域选择 RelativeLayout 布局类型,如图图 4-19 所示。然后点击完成按钮,在布局文件夹中创建 XML 文件,并在 Eclipse 的中央编辑窗格中打开。

9781430257462_Fig04-19.jpg

图 4-19。通过新的 Android XML 文件对话框创建一个 RelativeLayout 布局 XML 文件

现在,让我们将一些 ImageView 用户界面元素添加到相对布局容器中,这样我们可以稍后(在图形设计的章节中)添加一些行星图片作为视觉选择用户界面设计。

这次我们将使用图形布局编辑器(GLE)添加第一个 < ImageView > 标签,这样您就可以看到它的拖放功能是如何工作的。因为这是一本面向程序员的书,所以我们不会像在 Apress Absolute 初学者系列中关于如何创建 Android 应用的书中那样充分利用 GLE,但是您应该看看它是如何工作的,以防万一您想在自己的工作过程中使用它(而不是作为 XML 代码预览工具或快捷方式)。

单击中央编辑窗格左下方的选项卡,并选择图形布局编辑器模式。找到并点击左边的 Images & Media 抽屉,这样我们就可以访问 ImageView 用户界面元素,或者 widgets ,我们将在以后的 UI 设计第六章中更详细地了解它们。抓取 ImageView,如图图 4-20 所示,并将其拖动到模拟应用屏幕上,放在中央附近。

9781430257462_Fig04-20.jpg

图 4-20。使用图形布局编辑器窗格创建初始 ImageView 标签和参数

请注意,在拖放操作过程中,当您在屏幕上拖动 UI 元素时,工具提示会实时提供参数和位置信息。一定要尝试这个特性,因为它是一个很好的学习工具,可以帮助你了解哪些参数是可用的。放下 ImageView UI 元素后,单击屏幕底部的 xml 编辑选项卡(标记为 activity_add.xml ),查看为您生成的 XML 代码。它应该是这样的:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent" android:layout_height="match_parent" >
    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="146dp"
        android:layout_marginTop="164dp"
        android:src="@drawable/ic_launcher" />
</RelativeLayout>

注意,ImageView 标签下面有一条黄色波浪线,如果你将鼠标放在上面,它会告诉你缺少一个内容描述标签,Android 希望看到包含这个标签以帮助残疾人。添加新的一行,输入 android,然后输入冒号,在弹出的对话框中找到Android:content description参数。XML 标记应该是这样的,引用了一个字符串变量:

android:contentDescription="@string/content_desc_earth"

接下来,在我们复制它来创建我们的六世界选择器 UI 之前,让我们对这个 ImageView 标记做一些小的修改。将 android:id 更改为 imageEarth,并将 marginLeft 和 marginTop 更改为 5dp(或 5dip)值。事实上,因为两个边距值都是 5,所以让我们节省一行标记,简单地使用Android:layout _ margin = " 5dp "在我们的行星图像周围给我们均匀的间距。注意,现在,我们使用 drawable 文件夹中的启动器图标作为占位符图形,直到稍后我们在图形设计第六章中创建不同的世界图像。

因为我们在 ImageView 标签中引用了针对视障人士的内容描述字符串,所以接下来让我们添加六个星球内容描述字符串,然后结束。每个<字符串>标签的格式是

<string name="content_desc_planet">Planet Name</string>

让我们使用六个最常见的行星名称作为我们的字符串常量:地球、火星、金星、木星、土星和海王星。参见图 4-21 。

9781430257462_Fig04-21.jpg

图 4-21。将六个星球内容描述字符串标签添加到 values 文件夹中的 strings.xml 文件中

现在复制第一个 ImageView 标签并粘贴到下面,并将 ID 更改为 imageMars。让我们也删除 alignParentLeft 和 alignParentTop,因为它们仅用于左上角的 ImageView,以确保此 RelativeLayout 从布局(父容器)的左上角开始对齐。接下来,让我们添加一个引用 imageEarth ID 的 android:align_toRightOf 参数,因为我们希望的第二个 ImageView 与第一个 ImageView 对齐。还要更改 contentDescription 以引用@ string/content _ desc _ 火星

复制第二个 ImageView 标记并再次粘贴到下面。接下来将 ID 更改为 imageVenus 并将 layout_toRightOf 参数更改为 layout_below 并引用 imageEarth ID,因为我们希望第三个 ImageView 在第一个 ImageView 的下方对齐。另外,记得修改 contentDescription 标签来引用**@ string/content _ desc _ 维纳斯**。

复制第三个 ImageView 标记并再次粘贴到下面。将 ID 更改为 imageJupiter 并将 layout_below 参数更改为引用 imageMars,并添加一个引用 imageVenusandroid:layout_toRightOf 参数,以便 imageJupiter 位于 imageMars 的下方和 imageVenus 的右侧。编辑内容描述并指向**@ string/content _ desc _ 朱庇特**。

第一个标签相对于父容器对齐,其 XML 标记代码如下所示:

<ImageView android:id="@+id/imageEarth"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_margin="5dp"
        android:contentDescription="@string/content_desc_earth"
        android:src="@drawable/ic_launcher" />

请注意,一旦您复制了这个 XML 标记来创建其他所需的五个标签,您将不得不更改某些 android:layout 参数来正确对齐每个 ImageView UI 元素,相对于它周围的其他 UI 元素。如图图 4-22 所示。

9781430257462_Fig04-22.jpg

图 4-22。 RelativeLayout XML 标记定义添加一个新的带有占位符图形的 Planet screen 用户界面

最后,复制 imageVenus 和 imageJupiter 的最后两个 ImageView 标记,并将它们粘贴到 imageJupiter 下面,并将它们的 id 分别更改为 imageSaturn 和 imageNeptune。将它们的 contentDescription 引用更改为content _ desc _ 土星content _ desc _ 海王星,并将它们的 layout_below 参数分别更改为引用 imageVenus 和 imageJupiter。确保 imageNeptune ImageView 也有一个 android:layout_toRightOf 参数,该参数强制它与 imageSaturn 的右边对齐。六个完整的 ImageView 标签如图 4-22 所示。

定义配置行星活动:LinearLayout 容器

接下来,我们将创建我们的 Configure Planet UI 屏幕,这涉及到创建另一个名为ConfigActivity.java的活动子类,它带有一个在 activity_config.xml 文件中定义的 LinearLayout 容器。因为你已经这样做过一次,我将放弃截图和数字,因为如果需要的话,你可以参考前面的部分。

首先,右键单击 Hello_World 项目文件夹,选择 New image Class ,为 chapter.two.hello_world 包创建一个 Java 类,该类子类化 android.app.Activity,命名为 ConfigPlanet 。保留其他默认选项设置,点击完成

接下来,添加一个 onCreate( ) 方法到中,在 Android 中创建活动,使其存在。当您引用(访问)活动时,会调用此方法,并在系统内存中创建活动(在运行时为其分配内存)。这就是为什么每个活动都需要一个 onCreate()方法实现

接下来,添加一个 setContentView( ) 方法,该方法引用我们接下来创建的 activity_config.xml 来保存我们的 LinearLayout 定义,如下所示:

setContentView(R.layout.activity_config);

接下来,再次右键单击 Hello_World 项目文件夹,选择新的image Android XML 文件,并创建一个 LinearLayout XML 文件来定义 LinearLayout 用户界面设计。在此对话框中选择资源类型:布局,项目: Hello_World ,文件名: activity_config ,根元素: LinearLayout (参考图 4-19 ,点击完成

接下来,在我们的 LinearLayout 容器中添加一些按钮标签,这样您就可以看到 LinearLayout 做了什么。在后面的第五章中,我们将把它们连接起来,以便它们执行它们应该执行的任务,但是现在,我们只关心 XML 布局文件定义。单击 XML 编辑窗格底部的图形布局编辑器选项卡(窗格顶部的 activity_config.xml 选项卡应该是活动的),并将一个按钮 UI 元素从表单小部件抽屉中拖到模拟的应用屏幕上。然后切换到 XML 编辑窗格,将按钮标签的 android:id 值更改为 coloniesButton ,然后将 android:text 参数更改为引用我们接下来将创建的**@ strings/Button _ name _ colonies**值。这可以在图 4-23 中看到。

9781430257462_Fig04-23.jpg

图 4-23。用按钮 UI 元素填充 LinearLayout,以用于世界配置 UI 屏幕

每个标签应具有以下参数标记结构:

<Button android:id="@+id/coloniesButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_name_colonies" />

接下来,在第一个标记下再复制五次按钮标记,并编辑 ID 和文本参数值,以匹配每个按钮 UI 元素将要做的事情。因此,我们将殖民地分别改为殖民者、基地、军事、ffon(力场开启)和 ffoff(力场关闭)。

接下来,添加六个字符串标签,它们定义了每个按钮的文本标签,并通过 android:text 按钮标签参数引用,如下所示:

<string name="button_name_colonies">Add Colonies</string>
<string name="button_name_colonists">Add Colonists</string>
<string name="button_name_bases">Add Bases</string>
<string name="button_name_military">Add Military</string>
<string name="button_name_ffon">Forcefield On</string>
<string name="button_name_ffoff">Forcefield Off</string>

这里我将省略额外的截图,但是这些标签可以在稍后的图 4-25 中看到(以及我们需要为 AttackPlanet 类和 Activity 子类添加攻击方法的字符串标签)。

接下来,让我们继续创建我们的 TravelPlanet 类 Activity 子类,以及一个 FrameLayout 容器,以便稍后我们可以在我们的应用中添加星系间旅行的数字视频。

定义去行星旅行活动:框架布局容器

接下来,我们创建我们的 Travel to Planet UI 屏幕,这涉及到创建另一个名为TravelActivity.java的活动子类,它具有一个在 activity_travel.xml 文件中定义的 FrameLayout 容器。因为你以前做过这个,我将跳过大部分数字,因为你可以参考 NewPlanet.java 部分,如果你需要,它回到定义一个新的行星活动屏幕部分。

首先,右键单击 Hello_World 项目文件夹并选择 New image Class 并为 chapter.two.hello_world 包创建一个 Java 类,该类子类化 android.app.Activity 并命名为 TravelPlanet 。保留其他默认选项设置,然后点击完成

接下来,添加一个 onCreate( ) 方法来在 Android 中创建活动,以便它存在。当您引用(访问)活动时,会调用此方法,并在系统内存中创建活动(在运行时为其分配内存)。这就是为什么每个活动都需要一个 onCreate()方法实现

接下来,添加一个引用 **activity_travel.xml、**的 setContentView( ) 方法,我们接下来创建它来保存我们的 LinearLayout 定义,如下所示:

setContentView(R.layout.activity_travel);

接下来,再次右键单击 Hello_World 项目文件夹,选择 New image Android XML 文件,创建 FrameLayout XML 文件,用于定义 FrameLayout 用户界面设计。在此对话框中选择资源类型:布局,项目: Hello_World ,文件名: activity_travel ,根元素:框架布局(参考图 4-19 ,点击完成

接下来,在 FrameLayout 容器中添加一个 VideoView 标签。FrameLayout 是用于全屏数字视频的完美布局,因为 FrameLayout 只包含一个 UI 元素。在后面的章节中,我们将添加数字视频素材,但是现在,我们只关心我们的 XML 布局文件定义。

基本的 <视频视图> 标签 XML 标记实现如下:

<VideoView android:id="@+id/travelVideoView"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

这个 XML 标记嵌套在标签中,如图图 4-24 所示。

9781430257462_Fig04-24.jpg

图 4-24。向 Eclipse 中的 activity_travel.xml 文件添加 FrameLayout 容器和 VideoView UI 元素

单击 XML 编辑窗格底部的图形布局编辑器选项卡( activity_travel.xml 选项卡现在应该在编辑窗格的顶部处于活动状态),并将一个 VideoView UI 元素从 Images & Media 抽屉中拖到模拟的应用屏幕上。

接下来,切换到 XML 编辑窗格,将 VideoView 标签的 android:id 值更改为 travelVideoView 。这可以在图 4.24 中看到。

最后,我们添加了 AttackPlanet.java 类活动子类,以及另一个包含 ImageButton 标签的 LinearLayout。现在,我们已经为 Hello_World 应用建立了一个五屏幕框架,供本书剩余部分使用。

定义对行星活动的攻击:我们的第二个线性布局

接下来,我们在 Planet UI 屏幕上创建我们的 Attack,这涉及到创建另一个名为AttackActivity.java的活动子类,它具有一个在 activity_attack.xml 文件中定义的 LinearLayout 容器。因为你已经经历过了,我将放弃截图和数字,因为你可以参考定义添加一个新的行星屏幕部分,如果需要的话。

首先,右键单击 Hello_World 项目文件夹,选择 New image Class ,为 chapter.two.hello_world 包创建一个 Java 类,该类子类化 android.app.Activity,名为 AttackPlanet 。保留其他默认选项,点击完成

接下来,添加一个 onCreate( ) 方法来在 Android 中创建活动,以便它存在。当您引用(访问)活动时,会调用此方法,并在系统内存中创建活动(在运行时为其分配内存)。这就是为什么每个活动都需要一个 onCreate()方法实现

接下来,添加一个 setContentView( ) 方法,该方法引用: activity_attack.xml,,我们创建它来保存我们的 LinearLayout 定义,如下所示:

setContentView(R.layout.activity_attack);

接下来,再次右键单击 Hello_World 项目文件夹,选择 New image Android XML 文件,创建一个 LinearLayout XML 文件,用于定义 LinearLayout 用户界面设计。在此对话框中选择资源类型:布局,项目: Hello_World ,文件名: activity_attack ,根元素: LinearLayout (参考图 4-19 ,点击完成

接下来,在 LinearLayout 容器中添加一些 ImageButton 标签,这样我们就可以在我们的 Hello_World(或者我们应该命名为 Goodbye_World) Android 应用中添加一些攻击图标和功能。

请注意,在后面的章节中,我们将把它们连接起来,以便它们执行它们应该执行的任务,但是现在,我们只关心我们的 XML 布局文件定义。

在添加 ImageButton 标签之前,让我们首先定义它们将引用的四个标签。这些显示在截图底部的图 4-25 中。它们是在<资源>父标签容器中列出的最后四个<字符串>标签,其名称参数以:content_desc 开始。

9781430257462_Fig04-25.jpg

图 4-25。为我们的 activity_config.xml 和 activity_attack.xml 布局字符串引用添加字符串标签

有四个图形(图像或图标)按钮可以让我们对一个星球发起四种不同类型的攻击:轰炸、入侵、感染和激光。

因为 Android 中的图形(ImageView 和 ImageButton UI 元素)需要一个内容描述标记来帮助视觉障碍者,所以让我们在通过 android:contentDescription 引用的 strings.xml 文件(values 文件夹)中添加四个反映这些攻击模式的字符串常量,如下所示:

<string name="content_desc_bomb">Bomb the Planet</string>
<string name="content_desc_invade">Invade the Planet</string>
<string name="content_desc_virus">Infect Planet with Virus</string>
<string name="content_desc_laser">Fire Laser at Planet</string>

接下来,单击顶部的 activity_attack.xml 选项卡和底部的图形布局选项卡,并拖出一个 ImageButton UI 元素(参见 Images & Media)并选择应用启动器图标作为占位符图形以供使用。然后进入 XML 编辑模式,将其 ID 更改为 bombButton ,并添加字符串引用**@ string/content _ desc _ bomb**,指向刚刚添加的字符串标签。标签的<图像按钮>标记应如下所示:

<ImageButton android:id="@+id/bombButton
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:contentDescription="@string/content_desc_bomb"
             android:src="@drawable/ic_launcher" />

将它复制并粘贴到标签下方三次,并将炸弹 ID 参考更改为入侵、感染和激光,如图 4-26 所示,并将内容描述参考分别更改为入侵、病毒和激光。

9781430257462_Fig04-26.jpg

图 4-26。AttackPlanet.java 活动类的 activity_attack.xml 文件的 LinearLayout XML 定义

既然我们所有的活动和它们的布局容器都已经定义好了,我们要做的最后一件事就是在 AndroidManifest.xml 文件中使用标签向 Android OS 声明这四个新的活动屏幕。

将我们的应用活动添加到我们的 XML: AndroidManifest.xml

我们需要做的最后一件事是 100%确定我们在这一章中所做的一切都可以干净地编译和运行,那就是将我们对这些活动的使用声明添加到 AndroidManifest.xml 文件中。这是通过添加 <活动> 标签来实现的,每个标签定义一个活动的使用,并通过特定的命名约定为 Android OS 提供活动的名称。

标签和所需活动子类名称的格式如下

<activity android:name="chapter.two.hello_world.NewPlanet" />
<activity android:name="chapter.two.hello_world.ConfigPlanet" />
<activity android:name="chapter.two.hello_world.TravelPlanet" />
<activity android:name="chapter.two.hello_world.AttackPlanet" />

这里是所有四个标签,所以你可以看到在第二章中创建的 MainActivity 类标签之后,需要添加到 AndroidManifest.xml 文件中的内容。您可以看到对类名的完整引用包括包和类名。

正如您在图 4-27 中看到的,我们新的<活动>标签在 Eclipse 中没有“抛出”任何错误或警告。我的 android:targetSDKVersion 上有一个警告,说它不是最新版本,所以我将新的 android 应用项目助手放入此 < uses-sdk > 标签的 16 API 级别 Android 4.1.2 JellyBean 版本的值更改为当前的 17 API 级别 Android 4 . 2 . 2**Jelly Bean+**版本。正如我前面提到的,Eclipse ADT 可能会犯一些错误,您可能需要在以后修复这些错误!

9781430257462_Fig04-27.jpg

图 4-27。在 Hello_World AndroidManifest.xml 文件中添加四个< activity >标签来定义每个 activity 子类

为了确保我们在这一章中创建的一切都处于完美的工作状态(我们添加了许多令人印象深刻的 Java 代码和 XML 标记),我现在将在 Eclipse Package Explorer 中右键单击 Hello_World 项目文件夹,并选择 Run As Android Application 菜单序列来启动我们可信赖的 Nexus S 模拟器,并查看我们的应用是否可以运行。

在加载模拟器及其用户界面几分钟后,然后替换之前的应用屏幕,这个应用运行完美,我看到了与我们之前在图 4-4 中看到的完全相同的屏幕。

有时,如果新的应用版本没有出现,你可以在模拟器中单击运行上一个箭头(一个向左的、上下翻飞的箭头)(在右上角的按钮排上,第二行,左起第三个按钮),它会为你重新启动 Hello_World 应用(或者至少会加快一点速度)。咻!在这一章中,我们真的得到了一个的关键应用基础设施(活动屏幕,功能类,布局 XML)。拍拍自己的背!

摘要

在这一章中,我们学习了所有关于 Android 布局容器的知识,包括那些已经废弃(不再使用)的布局类型,以及那些最近为 API 14 到 17 (Android 4.x)开发使用而添加的布局类型。

然后,我们利用了三个最常用的屏幕布局容器,它们是当前可用的,并推荐用于所有 Android API 级别(API 3 到 17)的应用开发:容器 RelativeLayout 、容器 LinearLayout 和容器 FrameLayout

为了在我们不断发展的 Hello_World Android 应用中使用 XML 标记实现这些主流 Android 屏幕布局容器,我们为我们的应用设计并创建了四个新的 Activity 屏幕。然后,我们在这四个新的 Android Activity 子类中实现了三种不同类型的布局容器。

为了创建所有这些新的应用活动类,我们再次使用我们可信赖的新的image菜单序列来创建四个 Java 类,我们使用它们来通过 Android 活动支持我们的布局容器,Android 活动是 Android 应用的功能屏幕区域。

我们将这些新的 Java 类命名为:NewPlanet.java、ConfigPlanet.java、TravelPlanet.java 和 AttackPlanet.java,它们是 android.app.Activity 类的子类。我们现在已经从头开始创建了少数(五个)我们自己的定制 Java 类,我们只在第四章中!

我们学习了如何创建一个 Android Activity 子类,以及如何实现必要的 onCreate( )setContentView( ) 方法,这是为我们的每个 Hello_World 活动定义内存和屏幕区域所需要的。

当我们进行所有这些 Java 编码和 XML 标记时,我们还学习了 Eclipse IDE,以及它如何标记我们的错误,警告我们它希望看到实现的约定,并为我们提供帮助对话框,使我们的类、方法和变量选择更加容易。

我们学习了如何使用图形布局编辑器(GLE) ,以及 Eclipse central 编辑窗格底部的选项卡如何为我们提供不同的数据视图,而编辑窗格顶部的编辑窗格选项卡允许我们选择正在处理的代码或标记。

最后,我们将几个 <活动> 标签添加到我们的 AndroidManifest.xml 文件中,这样我们的四个新活动将被声明供 Android 操作系统使用(并且可见)。我们运行了新的应用代码,它成功了!

在下一章中,我们将开始把我们在本章中学到并创建的新屏幕布局、UI 元素和活动“连接”到我们在第三章中创建的 WorldGen 类和对象。我们将使用 Android 意图事件,两者都允许 Android 的活动和用户界面元素相互对话。