Android应用是使用Java编程语言编写的。Android SDK工具把代码、资源和数据文件编译为一个Android包,这是一个有.apk后缀的压缩文件。一个单独的.apk文件里包含全部的代码,这被看成一个应用,并且这个.apk文件是Android设备用来安装应用的文件。html
一旦在设备上安装了应用,那么每一个应用都在自已安全的沙盒里运行:java
1. Android操做系统是一个多用户的Linux操做系统,在这个系统里,每一个应用都是一个不一样的用户。android
2. 默认地,系统把每个应用都标识为一个独一无二的Linux用户ID(这个ID仅仅能够被系统所使用,对于应用程序来讲,它是不可见的)。系统为每一个应用的全部文件设置权限,所以,只有和应用用户ID相匹配的应用才能够读取应用的文件。数据库
3. 每一个进程都有自已的虚拟机(VM),所以,每一个应用的代码都独立地运行着。编程
4. 默认地,每一个应用都在它自已的Linux进程里运行。当应用的任何一个组件须要被执行时,Android系统都会运行这个进程,而后彻底停下再也不须要的进程,或者恢复其它应用占有的内存。安全
在这种方式中,Android系统实现了最小特权原则。也就是说,每一个应用默认都只能访问它完成工做所必须的组件,不会访问其它的。这样作就建立了一个很是安全的环境,在这样的环境里,若是一个应用不给分配权限的话,它就不能访问系统的任何内容。网络
虽然如此,可是,对于一个程序,把数据共享给其它应用,或者从系统服务中获取东东,有下面几种方法:app
1. 可让两个应用共享同一个Linux 用户ID,在这种状况下,这两个应用能够获取另一个的文件夹。为了保护系统资源,有相同用户ID的程序能够运行在同一个Linux进程中,共享着相同的虚拟机(应用程序也应该有着一样的证书签名)框架
2. 应用程序也能够经过请求权限的方式来获取设备的数据,好比联系人信息,短信,存储设备(SD card),照相机,蓝牙,等等。全部应用程序的权限在安装时候会展现给用户,用户赞成后才能安装。异步
关于Android应用程序如何在系统中存在的基本知识,本文档的其他部分向你介绍:
1. 定义了应用程序的核心框架组件。
2. 申明了应用程序用到的组件和所需的设备元素的mainfest文件。
3. 独立于应用代码的资源,可让你的应用极大的优化它在各类配置设备的表现
应用组件
对于一个Android应用来讲,应用组件是构建应用所必须的模块。每个组件都是一个不一样的点,系统能够经过这些点进入你的应用。对于用户来讲,不是全部的组件都是真正的入口点,可是这些组件之间都有着相互的依赖性-每一个组件都是独一无二的模块,这些模块有助于定义应用的总体行为。
有四种不一样类型的应用组件。每一种类型的组件都为一个明确的意图服务,也都有明确的生命周期,生命周期定义了如何建立和销毁它。
下面就是应用组件的四种类型:
Activity
一个Activity表明了用户界面的一个单独的屏幕。例如,邮件相关的应用或许应该有一个Activity来展现新邮件的列表,另一个Activity来写邮件,再一个Activity来读取邮件。虽然在邮件应用中这些Activity一块儿工做,造成了一个完整的用户体验,可是,每个部分又是独立工做的。例如,另一个应用能够启动上面这些Activity中的任何一个Activity(若是邮件应用容许的话)。例如,照相应用能够能够启动邮件应用里的写新邮件的应用,这样作对用户来讲,就能够分享照片了。
一个activity类就是一个实现了Activity 的Java类。在Activities开发者指导里,你能够获取更多的知识。
服务
服务是运行在后台,执行耗时较长的操做,或者甚至执行远程进程的操做。服务不提供用户界面。例如,当用户来到其它应用时,服务会负责在后台播放音乐,或者说,服务不会锁住用户和activity的交互,从网络上获取数据。好比一个activity,能够启动一个服务,并可让它运行或者邦定到这个activity,以便与其进行交互操做。
一个服务是做为Service子类来实现的,在Services开发指南中,你能学到更多关于它的使用。
Content providers - 内容提供
内容提供管理共享的应用数据集。你能够把数据存储在系统中,SQLite数据库中,内页中,或者其它任何你能够从中获取数据的本地持久性存储。经过内容提供,其它的应用能够查询数据,甚至修改数据(若是内容提供容许的话)。例如,Android系统提供了管理用户联系人数据的内容提供。这样的话,任何具备合适权限的应用均可之内容提供(例如ContactsContract.Data)来对一个指定的联系人进行读或写的操做。
内容提供对于操做你应用中没有共享的私有数据也是有用的。例如,Note Pad示例程序就使用了内容提供来保存笔记。
内容提供类是ContentProvider的子类,必须实现一系列标准的APIs,以让其它的应用能执行交换操做。在Content Providers开发者指导中,你能够学到更多的知识。
Broadcast receivers - 广播接收器
广播接收器是一个响应系统范围广播公告(通知)的组件。许多广播信息都来源于系统,好比,通知屏幕关闭的广播,系统电量低的广播,或者是拍了一张照片的广播。应用也能够建立广播,例如,在下载完某些数据时发送一条广播,让其它应用知道数据下载完成,可使用了。尽管广播接收器不显示一个用户界面,可是广播接收器能够建立一个状态栏通知,来通知用户。但更多状况下,一个广播接收者只是一个其余组件想要作极小量事件的一个"gateway”(途径)。举例,它可能发起一个服务,去执行关于某个事件的一些工做。
一个广播接收者,是看成BroadcastReceiver子类被实现的。每一个广播接收者都是从Intent对象衍生出来的。更多信息,请参考BroadcastReceiver。
Android系统设计的一个独一无二的方面是任何应用能够启动另一个应用的组件。例如,若是你想让用户使用设备的照相机进行拍照操做,拍照功能颇有多是另一个应用的功能,可是你的应用须要使用它,那你就不须要再在你的应用中开发拍照的功能了。你只须要调用拍照应用来进行拍照就能够了。拍照完成时,拍摄的照片会返回给你的应用,这样,你就能够对照片进行处理了。对于用户来讲,拍照功能好像就是你应用的功能同样。
当系统调用一个组件时,系统会开启组件所在应用的进程(这个应用可能没有运行)而且实例化组件所需的类。例如,若是你的应用调用拍照程序拍照的功能,那么系统就会启动照相的进程,这个进程属于拍照应用,不属于你的应用。所以,和其它系统里的应用不同,Android应用不只仅只有一个入口点(例如,没有main()函数)。
由于系统的每个应用,在一个有文件权限的单独的系统里运行,所以,其它应用不能访问,你的应用也不能直接激活其它应用的组件。虽然如此,可是,Android系统也能激活其它应用的组件,你必须给系统发送一个意图来启动一个指定的组件。而后,系统就会为你启动这个组件。
Activating components - 激活组件
四个组件类型中的三个:activity,service,broadcast receiver,是被叫作intent的异步消息激活的。在运行时,关于使用intent的更多信息,详情请参见Intents and Intent Filters章节。把一个单独的组件和其它组件相互绑定,而无论这个组件是否属于你的应用(你能够把它们想像为一个消息,一个用于请求其它组件的动做)。
一个Intent由一个Intent对象建立,在intent里,包含了一个激活组件的消息,这个组件要么是一个指定的组件,要么是指定类型的组件。能够是显式的,也能够是隐式的。
对于activity和service来讲,intent里定义了执行的动做(例如,转到一个视图或是发送一些消息等),也可能定义了数据在哪一个URI上执行(这些中的一些,是组件启动时就须要知道的)。例如,一个intent多是传递一个activity要浏览图片或是打开网页的请求。在某些状况下,你能够启动一个activity来接收这个结果,在这种状况下,activity会使用intent来返回结果(好比,你能够指示一个intent,让用户取一我的的联系方式,并返回给你,返回的intent中会包含一个指向选定联系方式的URI)。
对于广播接收器来讲,intent仅仅只是定义了被广播的公告的内容(设备电量低的广播仅仅只是包含了一个已知的字符串“battery is low”)。
对于内容提供组件来讲,它不会被intent激活,它会被内容解释者(ContentResolver)所请求的目标所激活的。内容解释者,处理全部与内容提供者的直接交换。因此组件不须要执行与提供者交换,而是调用ContentResolver对象方法。为了安全起见,组件请求信息与内容提供者之间有一个抽象层。
下面是分别激活这几种类型组件的方法:
1. 你能够经过给startActivity()或startActivityForResult()(若是你想让启动的activity返回一个结果)方法传递intent参数来启动一个activity(或是作一件新的事情)。
2. 你能够经过给startService()方法传递一个intent来启动一个service(或者给一个正在进行的service添加一些新的说明)。或者你能够经过给bindService()方法传递一个intent参数来绑定到service上。
3. 你能够经过给sendBroadcast()、sendOrderedBroadcast()、sendStickyBroadcast()方法传递一个intent来实例化一个广播。
4. 你能够经过在一个ContentResolver上调用query()方法来在一个内容提供上执行一个查询。
关于使用intent的更多信息,详情请参见Intents and Intent Filters章节。四种类型的组件也相应的提供了文档:Activities、 Services、 BroadcastReceiver 、Content Providers。
Minfest文件
在Android系统启动一个应用组件以前,系统必须经过读取应用的AndroidMainfest.xml。在这个文件中,你必须申明你在应用中所使用的全部的组件,该文件必须位于项目文件的根目录下。
为了申明应用的组件,mainfest文件作了一系列的事情,例如:
1. 标识程序所需的任何的权限,例如访问网络的权限,读取用户联系人的权限。
2. 申明应用运行时须要的最小的API Level,应用会基于这个API运行的。
3. 使用应用用到的或是须要的软硬件需求,例如照相机,蓝牙,或多点触摸屏。
4. 应用须要连接的API库(而不是Android框架API),好比Google Maps library。
5. 其它。
申明组件
mainfest文件最基础的任务就是通知系统应用有哪些组件。例如,mainfest能够按照下面展现的方式来申明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属性指定了用户可见的标签文本。
你必须使用下面的方式来申明应用的全部组件:
1. <activity> - activity组件
2. <service> - service组件
3. <receiver> - broadcast receiver组件
4. <provider> - content provider组件
在你项目中包含了,可是没有在mainfest文件里申明的activity、service和content provider组件,对于系统来讲是不可见的,固然,也是不能用的。虽然如此,可是,broadcast receiver要么在mainfest里申明,要么使用代码动态生成(使用BroadcastReceiver),而后经过调用registerReceiver()方法在系统里进行注册,这都是能够的。
关于如何为应用构建mainfest的更多知识,请参见The AndroidManifest.xml File文档。
申明组件功能
正如上面激活组件段落描述的那样,你可使用一个intent来启动activity、service和broadcast receiver。你也能够在intent中显式的指定目标组件(使用组件类名)。然而,intent真正的强大之处大于它的动做-即intent action。利用intent的动做,你只须简单的描述你要执行的action类型(作为可选操做,你能够给添加执行动做相关的数据),而且容许系统在设备上找到一个组件,这样就能够执行那个动做并启动它。若是有多个组件能够执行intent指定的action,那么用户能够选择执行哪个。
系统指定响应intent组件的方式是经过比较设备上其它应用的mainfest文件里提供的可接收的intent的过滤器后决定的。
当你在你应用的mainfest里申明了一个组件时,做为可选操做,你能够包括intent filters(意图过滤器)来指定组件的功能,这样的话,该组件就能响应来自其它组件的intent。你能够经过给申明组件的元素标签里添加<intent-filter>标签来给你的组件申明一个/组意图过滤器。
例如,包含写邮件页面的邮件应用或者会在mainfest里申明一个意图过滤器来响应发送的intent(为了能"send"邮件)。而后在你的应用中可建立一个有"send"动做的intent(ACTION_SEND),当你使用startActivity()方法来执行intent时,系统会匹配到邮件应用里的"send" activity并执行它。
关于使用intent的更多信息,详情请参见Intents and Intent Filters章节。
申明应用的需求
有不少的Android设备,可是它们中不是全部都提供一样的元素和能力。为了阻止你的应用安装在缺乏你应用所需元素的设备上,经过在你的manifest文件中声明软件硬件要求,明确的指出你的应用支持的硬件类型是很是重要的。大多数的申明只是信息的描述,系统也不会读取它们,可是外部的设备,好比Google商店,会读取它们,这样作的目的是,当用户在它们的设备上搜索应用时,能够提供过滤。例如,若是你的应用须要照相机,并且使用的是从Android(API Level7)开始引入的APIs,那么,你应该在你的mainfest文件里申明这些需求。这样作了,没有照相机、或者低于2.1版本的设备就不能从Google商店里安装你的应用了。
然而,你也能够申明你的应用使用了照相机,可是并不依赖于它。在这种状况下,当设备没有照相机而且照相功能被使用时,就须要你在应用运行时作检查,并作提示。
当你在设计和开发应用时,你应该考虑一些重要的设备特性:
1. 屏幕尺寸和密度。
为了经过屏幕类型来进行设备的分类,Android为每一个设备定义了两个特性:屏幕尺寸(屏幕的物理尺寸)和屏幕密度(在屏上的像素的物理密度,或者dpi--每英寸的点数)。为了简化屏幕配置的全部不一样类型,Android系统把它们分红可选的组,以便更容易定位。
屏幕大小:小,正常,大和极大
屏幕密度:低密度,中密度,高密度,和极高密度
默认状况下,你的应用是兼容全部屏幕尺寸和密度的,由于Android系统对此作了适当的调整,以使得它适合你的UI布局和图像资源
然而,你应为某个屏幕尺寸建立特殊的布局,并为某些密度提供特定的图像,使用可选的资源,并在你的manifest文件中用<supports-screens> 元素声明,以明确指出你的应用支持的屏幕尺寸.
更多信息,参考Supporting Multiple Screens文档。
2. 输入配置
许多设备为用提供了一个不一样类型输入装置,好比,硬件键盘,轨迹球,five-way导航pad.若是你的应用必需要一个特别的输入硬件,那么你应在你的应用中使用<uses-configuration>元素声明.但时,应用必需要一个特别的输入配置的状况是极少的。
3. 设备特性
在一个装有Android的设备中,有许多软硬件特性,有可能有,或有可能没有。好比照相机,光敏器件,蓝牙,或某个版本的OpenGL,或者触模屏的精度。你应该从不假设,在全部的装有Android的设备中某个特色是可用的(除了标准的Android库),因此你应该用 <uses-feature>元素声明你的应用支持的特征.
4. 平台版本
不一样的Android设备,常常运行不一样的Android平台版本,好比Android1.6或者2.3。每个成功的版本一般包括在前一个版本中不可用的API。为了指出,那些APIs集是可用的,每一个平台版本指定了一个API Level(好比, Android 1.0 is API Level 1 and Android 2.3 is API Level 9)。若是你使用的APIs是在1.0版以后,加入到平台的,你应该用<uses-sdk>元素,声明最小API级别,这样就指出了那些API将被采用。
为你的应用声明全部必要性的要求很是重要。由于,当你把你的应用发布到Android市场,市场将用这些声明信息来过滤出,哪些应用在每一个设备是可用的。 一样,你的应用应该只能在知足全部你应用需求的设备上才可用。
更多关于Android市场如何基于这些需求过滤的,请看Filters on Google Play文档
应用资源
一个Android应用不只仅由代码组成,它还须要从代码中分离出的资源,好比图片,音频文件,及与应用可显图像任何其余相关的。好比,你应该定义动画,菜单,风格,颜色,和用XML文件定义活动的布局。使用应用资源,能让你的应用在不修改任何代码的状况下容易的升级各类特性---而且经过提供一套可选取的资源--能优化你的应用在各类配置不一样的设备中的表现(好比不一样的语言和屏幕尺寸)。对于每一个包含在你的Android工程中的资源,SDK将其定义成一个惟一的整型ID,这样你就能够在你的代码中或在XML文件中定义的其余资源中引用它。若是你的应用包括一个图片名字是logo.png(保存在res/drawable/目录 ),SDK工具将生成一个资源ID命名成R.drawable.logo,你能够用它来引用图片,并插入你的用户界面中
提供与代码分开的资源的一个很重要的方面是,使得你能为不一样的配置的设备提供可选资源.好比,在XML中定义UI字串,你能够把字串翻译成各类不一样的语言并保存在不一样的文件中.而后,以基于语言限定词,你能够追加资源目录名(好比res/values-fr/ 用语法语资源),和用户语言设置,Android系会将相应的资源应用到你的UI中。
Android在可选资源上,支持许多不一样的qualifiers (限定词)。限定词是一个包括在你的目录名中的一个简短的字串,是为了定义那些资源将用在某些配置的设备上。再如,因为设备的屏幕的方向和尺寸不一样,你一般须要为你的活动定义不一样的布局.好比,若设备的屏幕是竖向(高),你可能要一个带有重直button 的布局,当屏幕是横向的(宽),按钮应是水平对齐的。要根据方向来改变布局,你要定义两个不一样的布局,并在布局的目录名中使用相应的限定词(qualifier)。而后,系统将自动根据当前的设备朝向来应用相应的布局.
要详细了解,你的应用中能包含的各类资源,及如何为各类配置的设备建立可选资源,请看Application Resources开发指南