Android 学习之路 之 Android应用结构分析(五)

使用 Eclipse 开发 Android 应用简单、方便,除了创建 Android 项目,开发者只要做两件事情:使用 main.xml 文件定义用户界面;打开 Java 源代码编写业务实现。但对于一个喜欢 “穷根究底” 的学习者来说,这种开发方式不免让他迷惑:

findViewById(R.id show);代码中的 R.id.show 是什么?从哪里来?

为何 setContentView(R.layout.hello_world);代码设置使用 hello_world.xml 文件定义的界面布局?

实际上,喜欢 “穷根究底” 的学习者才是真正好的学习者。借用拿破仑的一句话:不想当将军的士兵不是好士兵。类似地也可以说:不喜欢探究原理、机制的程序员不是好程序员。

每次看到那些局限于特定 IDE 工具、只能在特定 IDE 里做事,而且自我感觉良好的学习者、工作者,笔者忍不住十分遗憾:程序员,又少了一个。

下面将带领大家 “徒手” 开发一个 Android 项目,这样所有的事情都是由开发者自己完成的——自然对 Android 开发的每个细节更加熟知,以后用 IDE 工具开发才能做到不仅知其然,也知其所以然。

1,创建一个 Android 应用

前面介绍 android 命令时已经提到,该命令有个 create project 子命令,该子命令可用于 “手动” 创建一个 Android 应用,在命令行窗口输入如下命令:

android create project -n HelloWorld -t 8 -p HelloWorld -k org.crazyit.helloworld -a HelloWorld

上面的命令中,-n 选项指定创建项目的名称;-t 选项指定项目针对的 Android 平台;-p 选项指定该项目的保存路径;-k 选项指定请项目的包名;-a 选项指定 Activity 的名称。

运行上面的命令可以在当前目录的 HelloWorld 子目录下创建一个 Android 项目。进入该项目所在的目录,可以看到如下两个必要的文件夹:


上面的文件结构中 res 目录、src 目录、AndroidManifest.xml 文件是 Android 项目必需的。其他目录、其他文件都是可选的。

res 目录存放 Android 项目的各种资源文件,比如 layout 存放界面布局文件,values 目录下则存放各种 XML 格式的资源文件,例如字符串资源文件:strings.xml;颜色资源文件:colors.xml;尺寸资源文件:dimens.xml。drawable-idpi、drawable-mdpi、drawable-hdpi、drawable-xhdpi 这 4 个子目录则分别用于存放低分辨率、中分辨率、高分辨率、超高分辨率的 4 种圈片文件。

src 目录只是一个普通的、保存 Java 源文件的目录。

AndroidManifest.xml 文件是 Android 项目的系统清单文件,它用于控制 Android 应用的名称、图标、访问权限等整体属性。除此之外 Andriod 应用的 Activity、Service、ContentProvider、BroadcastRecevier 这 4 大组件都需要在该文件中配置。

除此之外,还可以在 HeIIoWorld 目录下看到一个 build.xml 文件,这是 Android 为该项目提供的一个 Ant 生成文件。通过该生成文件,开发者可以通过 Ant 来生成、安装 Android 项目。

与前面介绍的 Android 开发相似的是,此处的开发同样是先编辑 XML 格式的界面布局文件,再编辑相应的 Java 文件。编写文件的内容与前一个示例并没有太大的区别,此处不再赘述。

编辑完成后启动命令行窗口,并转入 HeIIoWorld 目录下,执行 ant 命令将可以看到如图 1.35 所示的输出。


从图 1.35 可以看出,Android 项目提供的 build.xml 文件包含如下常用的生成 target。

clean:清除项目生成的内容——也就是恢复原来的样子。

debug:打包一个调试用的 Android 应用的 APK 包,使用 debug key 进行签名。

release:打包一个发布用的 Android 应用的 APK 包。

test:运行测试。要求该项日必须是个测试项目。

install:将生成的调试用的 APK 包安装到模拟器上。

uninstall:从模拟器上卸载该应用程序。

Ant 是一个非常简洁,易用的项目生成工具。对于绝大部分 Java 开发者来说,使用 Ant 应该是一项最基本的技能。考虑到有些读者对 Ant 用法不熟,此处筒略介绍 Ant 的一些安装和使用方法。

1),登录 http://ant.apache.org/bindownload cgi 站点下载 Ant 最新版,笔者使用的是 1.8.2,建议下载该版本。Windows 平台下裁,zip 压缩包,而 Linux 平台则下载 .gz 压缩包。

2),将下载到的压缩文件解压缩到任意路径,例如,笔者解压缩到 D:\根路径下。

3),Ant 的运行需要如下两个环境变量:① JAVA_HOME:该环境变量应指向 JDK 的安装路径。如果已经成功安装了 Tomcat,则该环境变量应该已经是正确的。② ANT_ HOME:该环境变量应指向 Ant 的安装路径.Ant 的安装路径就是前面释放 Ant 压缩文件的路径。Ant 安装路径下应该包含 bin、docs、etc 和 lib 四个文件夹。

4),Ant 工具的关键命令就是 %ANT_HOME%/bin 路径下的 ant.bat 命令,如果读者希望操作系统可以识别该命令,还应该 %ANT_HOME%/bin 路径添加到操作系统的 PATH 环境变量之中。

经过上面 4 个步骤,即可在命令行窗口使用 ant.bat 命令了,它就是 Ant 工具。至于 Ant 更详细的用法介绍,请参阅疯狂 Java 体系的 《轻量级Java EE 企业应用实战》。

先执行 ant release 命令来发布该项目,发布完成后看到 HeIIoWorld 目录下出现了两个子目录。

bin:该目录用于存放生成的目标文件,如 Java 的二进制文件、资源打包文件(.ap_ 后缀)、Dalvik 虚拟机的可执行性文件 (.dex 后缀)等。

gen:该目录用于保存自动生成的、位于 Android 项目包下的 R.java 文件。

前而我们编写 Android 程序代码时多次使用了 R.layout.main、R.id.show、R.id.ok …… 现在读者应该明白这里 R 是什么了,原来它是 Android 项目自动生成的一个 Java 类。接下来将会详细介绍 R.java 文件。

2,自动生成的 R.java

打开 gen\org\crazyit\helloworld 目录下的 R.java 文件,看到如下代码。

/* AUTO-GENERATED FILE.  DO NOT MODIFY.
 *
 * This class was automatically generated by the
 * aapt tool from the resource data it found.  It
 * should not be modified by hand.
 */

package org.crazyit.helloworld;

public final class R {
    public static final class attr {
    }
    public static final class drawable {
        public static final int ic_launcher=0x7f020000;
    }
    public static final class id {
        public static final int ok=0x7f050001;
        public static final int show=0x7f050000;
    }
    public static final class layout {
        public static final int main=0x7f030000;
    }
    public static final class string {
        public static final int app_name=0x7f040000;
    }
}

通过 R.java 类中的注释可以看出,R.java 文件是由 aapt 工具根据应用中的资源文件来自动生成的,因此可以把 R.java 理解成 Android 应用的资源字典。

appt 生成 R.java 文件的规则主要是如下两条。

每类资源对应 R 类的一个内部类。比如所有界面布局资源对应于 layout 内部类;所有字符串资源对应 string 内部类:所有标识符资源对应于 id 内部类。

每个具体的资源项对应f内部类的一个 public static final int 类型的 Field。例如前面在界面布局文件中用到了 ok、show 两个标识符,因此 R.id 类里就包含了这两个 Field;由于 drawable-xxxx 文件夹里包含了 icon.png 图片,因此 R.drawale 类里包含了 icon Field。

随着我们不断地向 Android 项目中添加资源,R.java 文件的内容也会越来越多。后面还会详细介绍 Android 资源访问的相关内容,因此后面还会进一步随明不同资源在 R.java 文件中的表现形式。

3,res 目录说明

Android 应用的 res 目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片资源、字符串资源、颜色资源、尺寸瓷源等——后面还会进步介绍Android
应用中资源的用法,不过此处先对res目录的资源进行简单的归纳。
  Android按照约定,将不同的资源放在不同的文件夹内,这样可以方便地让AAPT工具
来扫描这些资源,井为它们生成对成的资源清单类:R_java,
    以/res/value/sirings.xml文件来说,该文件的内容十分简单,它只是定义了一条一条的‘产
符串常量,如以F代码所示。

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">HelloWorld</string>
</resources>

上面的资源文件中定义了—个字符串常量,称为 app_name。一旦定义了这份资源文件之后,Android 项目运行分别在 Java 代码、XML 代码中使用这份资源文件中的字符串资源。

1),在 Java 代码中使用资源

为了在 Java 代码中使用资源,AAPT 会为 Android 项目自动生成一份 R.java 文件,R 类里为每份资源分别定义一个内部类,其中每个资源项对应于内部类里一个 int 类型的 Field。

例如上面的字符串资源文件对应于 R.java 里的如下内容:

// 对应于一份资源
public static final class string {
    // 对应于一个资源项
    public static final int app_name=0x7f040000;
}

借助于 AAPT 自动生成 R 类的帮助,Java 代码中可通过 R.string.app_name 来引用到 “HeIIoWorld” 字符串常量。

2),在 XML 文件中使用资源

在 XML 文件中使用资源更加简单,只要按如下格式来访问即可:

@<资源对应的内部类的类名>/<资源项的名称>

例如我们要访问上面的字符串资源中定义的 “HelloWorld” 字符串常量,则使用如下形式即可:

@string/app_name

但有一种情况例外,当我们在 XML 文件中使用标识符时——这些标识符无须使用专门的资源进行定义,直接在 XML 文档中按如下格式分配标识符即可:

@+id/<标识符代号>

例如使用如下代码为一个组件分配标识符:

android:id="@+id/ok"

上面的代码为该组件分配了一个标识符,接下来就可以在程序中引用该组件了。

如果希望在 Java 代码中获取该组件,通过调用 Activity 的 findViewById() 的方法即可实现。

如果希望在 XML 文件中获取该组件,则可通过资源引用的方式来引用它,语法如下:

@id/<标识符代号>

4,Android 应用的清单文件:AndroidManifest.xml

AndroidManifest.xml 清单文件是每个 Android 项目所必需的,它是整个 Android 应用的全局描述文件。AndroidManifest.xml 清单文件说明了该应用的名称、所使用的图标以及包含的组件等。

AndroidManifest xml 清单文件通常可以包含如下信息:

应用程序的包名,该包名将合作为该应用的唯一标识。

应用程序所包含的组件,如 Activity、Service、BroadcastReceiver 和 ContentProvider 等。

应用程序兼容的最低版本。

应用程序使用系统所需的权限声明。

其他程序访问该程序所需的权限声明。

不管是 Eclipse 的 ADT 工具还是 android.bat 命令,它们所创建的 Android 项目都有一个 AndroidManifest.xml 文件。但随着不断地进行开发,可能需要对 AndroidManifest.xml 清单文件进行适当的修改。

下面是一份简单的 AndroidManifest.xml 清单文件。

<?xml version="1.0" encoding="utf-8"?>
<! -- 指定该 Android 应用的包名,该包名可用于唯一地表示该应用 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
	package="org.crazyit.helloworld"
	android:versionCode="1"
	android:versionName="1.0">
        <!-- 指定 Android 应用标签、图标 -->
	<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
                <!-- 定义 Android 应用的一个组件:Activity 该 Activity 的类为 HelloWorld,并指定该 Activity 的标签 -->
		<activity android:name="HelloWorld" android:label="@string/app_name">
			<intent-filter>
                                <!-- 指定 Activity 是程序的入口 -->
				<action android:name="android.intent.action.MAIN" />
                                <!-- 指定加载该应用时运行该 Activity -->
				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
		</activity>
	</application>
</manifest>

上面这份 AndroidManifest.xml 清单文件中的注释已经大致说明了各元素的作用,故不再详细说明每个元素。上面的清单文件中有两处用到了资源:

android:label="@string/app_name",这说明该应用的标签(Label)为 /res/value 目录下 string.xml 文件中名为 app_name 的字符串值。

android:icon="@drawable/ic_launcher",这说明该应用的图标为 /res/drawable-l/m/hdpi 目录下主文件名为 icon 的图片。

5,应用程序权限说明

一个 Android 应用可能需要权限才能调用 Android 系统的功能;一个 Android 应用也可能被其他应用调用,因此它也需要声明调用自身所需要的权限。

1),声明运行该应用本身所需要的权限

通过为 <manifest.../> 元素添加 <uses-permission.../> 子元素即可为程序本身声明权限。

例如在 <manifest.../> 元素里添加如下代码:

<!-- 声明该应用本身需要打电话的权限 -->
<uses-permission android:name="android.permission.CALL_PHONE"/>

2),声明调用该应用所需的权限

通过为应用的并组件元索,如 <activity.../> 元素添加 <uses-permission.../> 子元素即可声明调用该程序所需的权限。

例如在 <activity.../> 元素里添加如下代码:

<!-- 声明该应用本身需要发送短信的权限 -->
<uses-permission android:name="android.permission.SEND_SMS"/>

通过上面的介绍可以看出,<uses-permission...> 元素的用法倒不难,但到底有多少权限呢?实际上 Android 提供了大量的权限,这些权限都位于 Manifest.permission 类中。一般来说有如表 1.1 所示的常用权限。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值