首页 > 代码库 > Android之应用开发基础

Android之应用开发基础

Android应用开发基础

英文地址:http://developer.android.com/guide/components/fundamentals.html
本人英语水平不高,如有翻译不当请指正。

文档文件夹

  1. 1 应用组件
    1. 1.1 Activating组件
  2. 2 清单文件
    1. 2.1 声明组件
    2. 2.2 申明组件的能力
    3. 2.3 声明应用必须须要的设备功能
  3. 3 应用资源

Android 应用是基于Java程序语言的。Android SDK 工具编译你的代码以及不论什么数据和资源文件到一个APK(全称“an Android package”)。那是一个.apk后缀的归档文件。

一个APK 文件包括Android应用所需的全部内容 。apk文件是Android设备的应用程序的安装文件。

一旦安装在设备上,每一个Android应用程序都存在于它自己的安全沙箱:

  • 操作系统是一个多用户Linux系统,系统中的每一个应用程序是一个不同的用户。
  • 默认情况下,系统分配给每一个应用程序的一个唯一的Linux用户ID(ID是系统唯一而且系统也不知道这个ID属于这个应用)。系统给一个应用程序中的全部文件设置权限,仅仅有与用户ID同样的应用程序能够訪问它们。
  • 每一个进程都有自己的虚拟机(VM),所以应用程序的代码执行在与其它应用程序相隔离的进程中。
  • 默认情况下。每一个应用程序执行在它自己的Linux进程中。Android应用启动过程中。不论什么应用程序的组件都须要被执行。应用程序长时间没有响应或者系统须要收回内存的时候,应用程序会被关闭。

这样,Android系统实现了最细粒度的权限原则。

在默认情况下。每一个应用程序仅仅能使用自己能訪问的组件来做它须要做的工作。这将创建一个很安全的环境。应用程序不能訪问它没有权限的系统部分。

然而,应用程序与其它应用程序之间以及一个应用程序与系统服务之间,能够有这种数据共享方式:

  • 让两个应用程序共享同样的Linux用户ID。这是可能的,在这样的情况下,他们能够訪问彼此的文件。为了节约系统资源,具有同样用户ID的应用程序也能够执行在同样的Linux进程共享同样的虚拟机(应用程序也必须使用同样的证书签名)。

  • 一个应用程序能够请求对系统数据的訪问权限,如用户的联系人。短信。可插拔的存储设备(SD卡),摄像头。蓝牙,等等。全部的应用程序权限必须由用户在安装时授予,也就是在清单文件AndroidManifest.xml上要列举该应用须要哪些权限。

本文档主要介绍一个Android应用程序的基础知识。文档其它部分会介绍:

  • 定义你的应用程序中的核心框架组件。
  • 在你的应用程序清单文件里声明组件和所需设备功能。
  • 资源是独立于应用程序代码的。这能让你的程序为各种设备配置资源进行优化。

1 应用组件


应用程序组件是一个Android应用程序的基本构造块。每个组件都是一个不同的点,通过这个点能够从系统进入你的应用程序。不是全部的组件都是一个实际的切入点。但每个存在的实体。扮演着特定的角色,每个都是独特的构建块。能让你规定你的应用程序的总体行为。

有四种不同类型的应用程序组件。

每一个类型都有不同的目的,有不同的生命周期,有不同的创建和销毁规则。

这里有四种类型的应用程序组件:

Activities
一个Activity代表了一个用户界面。比如,一个电子邮件应用程序可能有一个Activity显示新邮件列表,一个Activity撰写邮件,一个Activity来读取邮件。

尽管Activity一起形成了电子邮件应用程序。一个完整的用户界面,但每个Activity都是独立的。因此,不同的应用程序能够启动这些Activity的不论什么一个(假设邮件应用程序同意的话)。比如。一个摄像头的应用程序为了让用户分享图片,能够调用电子邮件应用程序中的编写新邮件的Activity。

每个Activity都是实现 Activity 的子类,你能够学习很多其它关于Activities的开发指南。

Services
Service组件执行在后台执行长时间执行的操作或执行远程操作。

Service不提供用户界面。比如。一个Service能够在后台播放音乐,当用户切换不同的应用程序时。也能够从网络上获取数据,而不堵塞用户界面和活动。还有一个组件,如Activity,能够启动Service,并让它执行或绑定到它,与它进行交互。

每个Service都是实现 Service  的子类,你能够学习很多其它关于Services的开发指南。

Content Providers
ContentProvider管理应用程序的共享数据集。

你能够将数据存储在文件系统中,一个SQLite数据库上,互联网上。或不论什么其它应用程序能够訪问持久存储的位置。通过ContentProvider。其它应用程序能够查询或改动数据(假设ContentProvider同意)。

比如,Android系统提供一个ContentProvider管理用户的联系人信息。因此,不论什么拥有适当权限的应用程序能够查询ContentProvider的某一部分(如 ContactsContract.Data)来读取和写入一个特定的联系人信息。

ContentProvider也可用于读取和写入你自己应用程序私有而不是共享的数据。

比如,记事本演示样例应用程序使用ContentProvider保存笔记。

每个ContentProvider都是实现 ContentProvider 的子类。你能够学习很多其它关于 Content Providers 的开发指南。

Broadcast Receivers
BroadcastReceivers是一个响应系统广播通告的组件。很多广播起源于系统,比如。广播通知屏幕已经关闭,电池低,或图片拍摄。应用程序也能够进行广播。比方,让其它应用程序知道某些数据已经下载到设备。其它应用能够開始使用。尽管BroadcastReceivers不显示用户界面,但他们能够创建状态栏通知用来提醒用户一个广播事件的发生。更常见的是,BroadcastReceivers是一个“入口式”的进入其它组件。仅仅做一点点工作。比如,它可能会启动一个服务来运行基于事件的一些工作。

每个BroadcastReceivers都是实现BroadcastReceiver的子类,每个广播作为一个Intent 对象传递的实现。很多其它信息參见BroadcastReceiver类。

Android系统的一个独特的方面是不论什么应用程序能够启动还有一个应用程序的组件。比如。假设你想让用户用照相机拍一张照片。可能有还有一个应用程序须要使用它,取代应用程序自己开发一个Activity用来拍摄照片。你不须要包括或者连接到相机的应用程序代码。

相反。你能够简单的启动一个Activity,在相机拍摄照片的活动完毕时能够获得照片,照片会返回到你的应用程序,所以你能够使用它。对用户来说,相机就好像是你的应用程序的一部分。

当系统启动一个组件,它会首先启动应用进程(假设它不是已经在执行)和实例化该组件所须要的类。比如,假设你的应用程序启动相机应用程序拍摄照片的Activity,这些Activity是属于摄像头应用程序的程序,而不是在你的应用程序的程序。

因此,不像非常多其它系统上的应用程序,Android应用程序没有一个单一的入口点(没有main()函数)。

由于系统执行每一个应用程序在一个单独的进程,并限制其它应用程序訪问该应用程序的文件,你的应用程序不能直接激活还有一个应用程序的组件。

只是在Android系统中,假设你的应用程序要激活还有一个应用程序的组件,你必须向系统发送一条消息。指定你的Intent来启动某个组件,然后系统为你激活那个应用程序的组件。

1.1 Activating 组件

三四种类型的组件如Activity,Service。和BroadcastReceivers是由一个叫做Intent的异步消息激活。

在执行时,Intent能把相互独立的组件联结在一起(你能够把它们作为使者,请求一个动作从其它组件),不用管这个被联结的组件是属于你的应用程序还是还有一个应用程序。

一个Intent是一个创建了的 Intent 对象,它定义了一个消息来启动某个组件。Intent启动组件的方式能够是显式或隐式的。

关于Activity和Service。一个Intent定义要运行的操作(比如。“展示”或“发送”东西),能够指定操作数据的URI(将要启动的组件在其它事情上或许须要知道)。比如。一个Intent或许会用一个Activity来显示图像或请求打开一个网页。

在某些情况下。您能够启动一个Activity来接受结果,在这样的情况下。这个Activity也返回这个Intent返回的结果(比如。你能够发起一个Intent,让用户选择一个联系人并返回给你。这个返回的Intent则包含一个URI指向选定的联系人)。

关于BroadcastReceivers。Intent仅仅定义了通知广播(比如,广播指示设备电池电量低时仅仅包含一个已知的行为字符串表示“电池电量低”)。

其它的组件类型。ContentProvider,它没有激活的Intent。

相反,它被激活时,有针对性的从一个ContentResolver发出请求。ContentResolver处理全部直接事务与ContentProvider。使组件不须要运行事务和ContentProvider。而是调用ContentResolver对象的方法。这就留下一个内容提供者和组件请求信息之间的抽象(安全)层。

这是分别激活每种组件的方法:

  • 你能够启动一个Activity(或给新的事情让它做)通过一个Intent来startActivity()或者startActivityForResult() (当你想要Activity返回结果)。

  • 你能够启动一个服务(或给予一个正在执行的服务新的指示)通过传递一个Intent来startService()。或者你能够绑定到服务通过传递一个Intent来 bindService()
  • 你能够通过传递一个Intent去用法 sendBroadcast(),sendOrderedBroadcast(), or sendStickyBroadcast()发起广播。
  • 你能够使用 ContentResolver的 query() 去查询ContentProvider提供的数据查询。

Activities, Services,BroadcastReceiver 和 Content Providers.关于使用Intent的很多其它信息。请參见 Intents 和 Intent Filters 文档。

关于激活特定组件的很多其它信息也被提供在下面文档: Activities, Services,BroadcastReceiver 和 Content Providers。

2 清单文件


在Android系统启动一个应用程序组件之前,系统必须通过阅读程序的AndroidManifest.xml文件知道组件的存在。

你的应用程序必须在这个文件里声明的全部组件。它必须在应用程序项目的根文件夹。

清单除了声明应用程序的组件,还做一些其它的事情。如:

  • 向用户标明该应用须要哪些权限,如连接互联网和訪问用户的通讯录。

  • 声明应用程序所需的最低API版本号,基于哪个API版本号的应用程序能够使用。

  • 声明须要使用设备中软硬件的哪些功能,如照相机,蓝牙服务,或者是多点触控屏幕。

  • 应用程序须要链接哪些API库(除了Android框架API之外)。如 Google Maps 库。
  • 其它

2.1 声明组件

清单的首要任务是告诉系统应用程序中有哪些组件。比如。清单文件能够声明一个Activity。例如以下:

<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:icon="@drawable/app_icon.png" ... >
        <activity android:name="com.example.project.ExampleActivity"
                  android:label="@string/example_label" ... >
        </activity>
        ...
    </application>
</manifest>

在 <application> 元素中,这个 android:icon 属性是一个标识应用程序的资源图标。

在 <activity> 元素中, android:name 属性指定这个Activity的类名,和 android:label 属性指定一个字符串作为Activity的用户可见的标签。

你必须用这样的方式声明应用程序中用到的全部组件:

  • <activity> 元素用来声明Activity
  • <service> 元素用来声明Service
  • <receiver> 元素用来声明BroadcastReceiver
  • <provider> 元素用来声明ContentProvider

Activity,Service和ContentProvider包含在你的源码中。但假设你不声明在清单上,系统是看不到这些组件的,因此,应用程序也就不能执行。

然而,BroadcastReceiver既能够在清单文件里定义也能够通过代码动态创建(如BroadcastReceiver对象)和注冊的系统调用 registerReceiver()

很多其它关于怎样构建你的应用程序清单文件。查看 AndroidManifest.xml 文档。

2.2 申明组件的能力

如上所述,在 Activating组件 中,你能够用一个Intent来启动Activity。Service和BroadcastRecaiver。

你能够使用显式地指定目标组件(使用组件类的名称)的Intent。然而。Intent真正牛逼的地方在于隐式的Intent。一个隐式Intent简单描叙动作类型并运行(而且你能够运行随意你想要的动作),隐式的Intent同意系统在设备上查找相匹配的组件并启动它。假设匹配到多个组件能够运行Intent所描写叙述的动作。那么就会让用户选择使用哪一个。

这样的系统能识别可响应Intent的组件,是通过比較Intent在其它应用程序的清单文件提供的Intent过滤器来获得的。

当你声明一个Activity在你的应用程序清单中,你能够包括Intent过滤器来申明Activity的能力。所以它能够响应来自其它应用程序的Intent。你能够通过为组件加入一个 <intent-filter>元素,作为组件声明元素的子元素,用来定义一个Intent过滤器。

比如。假设你有一个在写新邮件的Activity须要调用一个电子邮件应用程序,你能够定义一个Intent过滤器来响应“发送”的Intent(为了发送新邮件)像这样:

<manifest ... >
    ...
    <application ... >
        <activity android:name="com.example.project.ComposeEmailActivity">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <data android:type="*/*" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

然后。假设还有一个应用程序创建 ACTION_SEND Intent而且通过它 startActivity(),那么系统能够启动你的Activity。用户能够起草和发送电子邮件。

很多其它关于创造Intent过滤器,请參考 Intents and Intent Filters 文档。

2.3 申明应用必须须要的设备功能

有各种各样的机器设备。他们不能提供全部功能和能力。

为了防止你的应用程序被安装在一个“缺少你必须须要的功能”的设备上,重要步骤是你必须在清单文件里明白定义一些配置来表明哪些类型的设备才干支持你应用。大多数的这些声明只不过信息,系统不读它们,但外部服务如Google Play(谷歌应用商店)在排序和过滤用户搜索时。会在他们的设备上阅读应用程序的这些申明。

比如,假设你的应用须要一个摄像头和使用Android2.1的API(API Level 7),你应该在你的清单文件里声明这些要求这样:

<manifest ... >
    <uses-feature android:name="android.hardware.camera.any"
                  android:required="true" />
    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" />
    ...
</manifest>

如今,没有一个相机和一个Android版本号低于2.1的设备无法从Google Play(谷歌应用商店)安装你的应用程序。

然而,你也能够声明你的应用程序使用相机,但不是必须须要它。在这样的情况下,你的应用程序必须设置须要的属性 required 为 "false" 。并在执行时设备是否有一个摄像头和禁用不论什么相机的时候适当的检查。

很多其它的信息关于怎样管理应用程序在不同设备的兼容性请參考Device Compatibility 文档。

3 应用资源


一个Android应用程序不不过代码组成的,它须要与源码分离的资源,如图像,音频文件,以及不论什么与该应用程序的视觉呈现。比如,你应该定义动画,菜单,款式。颜色。以及用户界面的布局XML文件。使用应用程序资源,能够非常easy地更新你的应用程序的各种特性,而无需改动代码,通过提供替代资源集使您能够为不同的设备配置优化你的应用程序(如不同的语言和屏幕大小)。

对于你Android项目中的每个资源,SDK构建工具都会自己主动为这个资源定义一个唯一的ID。你能够在你的应用程序代码或XML文件里,使用资源ID去引用你定义的资源。

比如,假设你的应用程序包括一个名为 logo.png 的图片文件(保存在 res/drawable/ 文件夹)。SDK工具生成一个名为 R.drawable.logo资源ID,您能够引用图像插入你的用户界面。

一个提供资源从源码中分离的最重要的方面是你为不同的设备配置提供替代资源的能力。比如,通过在XML中定义UI字符串,你能够把字符串翻译成其它语言并保存在不同的字符串文件里。

然后,基于一个“language qualifier”你能够追加资源文件夹的名称(比如 res/values-fr/ 表示法国字符串值)用来配置不同的用户语言,Android系统会应用合适的语言字符串UI。

Android系统能够支持非常多不同的资源限定符。

限定符是一个短字符串,包括你的资源名称和文件夹名称,在有序的定义配置下。设备会选择使用某一个资源。还有一个样例,你应该常常为你的Activity创建不同的布局,依据设备的屏幕方向和大小。比如。当设备屏幕是纵向的(高),你可能会想要一个有button的布局是垂直的,但当屏幕是横向的(宽),button应水平对齐。

依据方向改变布局,你能够定义两个不同的布局和应用适当的限定词在布局的文件夹名。然后。系统自己主动使用适当的布局会取决于当前设备的方向。

很多其它关于不同种类的资源,你能够在你的应用程序以及怎样为不同的设备配置,创造替代资源,请阅读 Providing Resources。

继续阅读:

Intents and Intent Filters
有关怎样使用 IntentAPI激活应用程序的组件,如活动和服务,以及怎样使你的应用程序的组件可用于其它应用程序。

Activities
有关怎样创建Activity类的一个实例,并提供一个用户界面应用程序的不同的屏幕。
Providing Resources
关于Android应用程序的结构。将资源从应用程序代码中的信息。包含你能够为特定的设备配置提供替代资源。


Android之应用开发基础