到目前为止,我们可以由学习 Android 应用程序的经验中归纳得出:所有 Android 程序的运作流程,都定义在 Activity 中。
Android 系统与其他系统很不一样的地方是:它的应用程序并不直接与底层系统紧密结合,而是跑在 Android 框架中。这意思是设计 Android 应用程序时,我们并不需要关心实际上运作的机器是哪一牌的手机或是哪一种嵌入式系统,或使用哪一种架构 (ARM、x86、MIPS)。我们要关心的只有 Android 框架提供了那些功能,好让我们能操作这台设备。
在执行"startActivity" 函数时,应用程序并不是直接呼叫另一个 Activity ,而是将"Intent"( 意图 ) 传进 Android 框架中。 Android 框架会查看 "startActivity" 呼叫所传入的动作与 Intent 内容是否在注册表中,如果符合,就启动对应的服务或 Activity。
Android 系统中的每一个应用程序,在安装的过程里,都得事先在 Android 框架中注册、登记这个应用程序所建立的 Activity,并事先注明会使用到的服务。譬如当我们在Android 上安装我们撰写的 BMI 应用程序时, BMI 应用程序就会向 Android 框架登记相关信息: BMI 应用程序将会用到 "Bmi" 这个 Activity。
这份信息存在于每个 Android 应用程序工程根目录下的 "AndroidManifest.xml" 文件中。如果我们在程序里,要用到其他应用程序或服务所提供的功能,也需一并在此列出。在安装应用程序的时候, Android 框架会根据应用程序提供的这份清单,将信息注册于Android 框架的注册表中。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo.android.bmi"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="3" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:label="@string/app_name"
android:name=".Bmi" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
package="com.demo.android.bmi"
"package" 是 "manifest"( 清单 ) 标签的一个特别属性,范例中的内容可用来标明,这个应用程序的进入点存在于 "com.demo.android.bmi" 这个名称空间 / 路径中。
android:versionCode="1"
android:versionName="1.0"
"android:versionCode"和 "android:versionName" 是应用程序版本号。这两个属性是可选的(非必要)。
"android:versionName"是给使用者看的版本号, 如"1.0" 、"2.0" 。"android:versionCode" 则是开发者用的内部版本号,一般使用流水号。
<application
android:icon="@drawable/icon"
android:label="@string/app_name">
......
</application>
"manifest" 标签中主要包含一个 "application" 标签。 "application" 标签里面,定义了所有这个应用程序用到的 Activity 、服务等信息。 "application" 标签中的 "android:icon" 属性,定义了这个应用程序将显示在 Android 主画面中的应用程序图示。图示的大小必须超过 64x64 像素(Pixel) 。"application" 标签中的 "android:label" 属性可用来指定应用程序将显示在Home主画面上的名称。
备注:除了 "application" 标签外,还有 "uses-permission"( 例如允不允许存取 SMS 、能否存取联络簿、相机功能 ) 、 "permission" 、 "instrumentation" 等主要标签。
<activity
android:name=".Bmi"
android:label="@string/app_name">
...
</activity>
"application" 标签中所有用到的 Activity ,都要包含在一个个 "activity" 标签中。Activity 是 Android 应用程序与使用者互动的主要元素,当使用者开启一个应用程序,第一个看到的画面就是一个 Activity 。若是一个应用程序中包含多个画面时,会定义多个不同的 Activity ,我们也必须在 "application" 标签中,使用多个 "activity" 标签,为不同的 Activity添加描述。如果我们已经在程序中定义好了 Activity ,却忘了在 "AndroidManifest.xml"文件中加入对应的 "activity" 标签,那么在执行中呼叫到这个 Activity 的时候,将无法开启这个 Activity 。
"android:name" 属性,指出了这个 Activity 所对应的类别 (class) 。
因为在上一 层 "Manifest" 标签属性中已经定义了 "package="com.demo.android.bmi", 因此在 "activity" 标签的 "android:name" 属性中, ".Bmi" 代表着 "com.demo.android.bmi.Bmi" 的简写。也可以写成 "Bmi" ,一样是代表 "com.demo.android.bmi.Bmi" 这个类别。
"android:label" 属性可用来指定应用程序将显示在 Activity 画面上方的名称。也可以在程序中透过 "setTitle( “ 名称 ” )" 来动态修改。
备注:除了 "activity" 标签外,对应于 Android 应用程序的运作流程,还有 "service" 、 "receiver " 、"provider" 等主要元件。
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
/intent-filter>
"intent- filter" 标签定义了这个 "activity" 的性质。 "intent-filter" 中主要包含了两个标签:"action" 跟 "category" 标签。 "action" 标签中的 "android:name" 属性,其内容"android.intent.action.MAIN" 表示:这个 Activity 是此应用程序的进入点(就像程序中常见的 main 主程序),开启这个应用程序时,应先执行这个 Activity 。常见的还有"android.intent.action.EDIT" 等标签。
"category" 标签中的"android:name" 属性,其内容 "android.intent.category.LAUNCHER" 表示:这个 Activity 将显
示在 Launcher 的应用程序列表中。
我们把整个文件合到一起看,可以总结出这个文件所传达的信息: 在"com.demo.android.bmi" 路径下的 "Bmi.java" 这个文件中,已定义了一个主要的 Activity; 当我们打开 Android 的时候,显示的是位于 "res/drawable/icon" 的图示。一旦我们按下图示来
启动这个应用程序, Android 应用程序框架会去寻找到定义了 "android.intent.action.MAIN"内容的 ".Bmi"activity ,并呼叫执行。
<uses-sdk android:minSdkVersion="3" />
Android SDK 1.1 版之后引入了这条叙述。透过指定这个参数,系统可以依此辨别应用程序是否使用相容的 SDK 版本,好决定能否在这台机器上安装执行。 "1" 代表 Android SDK1.0 , "2" 代表 SDK1.1 , "3" 代表 SDK1.5 。这也是一个可选填的选项。但如果我们的应用程序要发布出去,一些强势的通路如 Google Android Market 已规定所有新发布的应用程序必须指定 "android:minSdkVersion" 这个参数。