Android应用的基本原理

原文:http://android.eoe.cn/topic/android_sdkjava

应用基础-Application Fundamentals

Android应用程序以java做为开发语言。用Android SDK 提供的工具,能够将应用程序所须要的数据和资源文件打包到一个android包文件中,这个文件用.apk做为扩展名。全部代码都在单个.apk文件中,当成一个应用,这个文件就是一般安装在Android设备中的应用.
一旦安装到了一个设备,每一个应用生存在它本身的安全沙箱中。linux

    • 一个Android系统是一个多用户的Linux系统,其中的每一个应用都是一个不一样的用户。
    • 默认状况下,系统给每一个应用分配一个独立的Linux用户ID(这个ID只由系统使用而且对应用来讲是不可知的),系统给在某个应用中的全部文件设置了权限,因此只有分配了那个用户ID的应用才能访问它们
    • 每一个进程拥有它本身的虚拟机,因此一个应用代码的运行,与其余应用代码的运行是隔离的.
    • 默认状况下,每一个应用程序均运行于它本身的Linux进程中。当应用程序中的任意代码开始执行时,Android启动一个进程,而当再也不须要此进程而其它应用程序又须要系统资源时,则关闭这个进程。

经过这种方法,Android系统实现了最小特权原则。默认,每一个应用仅仅访问须要工做的组件,并很少作其余的事。这样建立了一个很是安全的环境,应用不能访问系统没有受权的其余部分.android

然而,应用能够有多种方法来与其余应用,共享数据及访问系统服务:数据库

  • * 有可能安排两个应用共用一个linux用户ID,在那种状况下,它们能互相访问相互的数据。为了节约系统资源,拥有相同用户ID的应用,可能也被安排运行在同一个Linux进程中并共享相同的VM(应用必须被签名成一样的认证)。
  • * 全部应用能请求容许访问硬件数据,好比像用户通讯录,SMS消息及可挂载的存储设备(SD card),摄像头,蓝牙等,全部应用的权限必须在用户安装时被许可。

上述了一个应用怎样存在于一个系统中的相关基本概念,这个文档的其余部分将向你介绍以下 内容:安全

  • * 定义在你的应用中核心框架组件
  • * 在manifest中,给你的应用,声明组件及设备特色请求
  • * 独立于应用代码的资源,可让你的应用极大的优化它在各类配置设备的表现

应用组件-Application Components


应用组件是构建Android应用程序的关键和基石。 每一个组件是一个不一样的入点,系统能够从这些点进入到你的应用。对于用户来讲,并非每一个组件都是实际的入点,但它们之间有一些依赖.可是每个存在的组件都有它本身的一个入点,并扮演一个特定的角色--每个都是独一无二的构建块,帮助你定义你的应用的总体行为.网络

有四个不一样类型的应用组件,每一个类型服务于一个不一样的目的,并有不一样的生命周期,生命周期定义了如何建立和销毁它.app

下面是四种应用组件:框架

Activities活动

    • 一个activity在一个屏幕,显示一个用户接口.好比,一个email应用可能有一个activity,这个activity用于显示新的email列表.而另外一个activity用于写邮件,还有一个activity用于读取邮件.虽然这些activities一块儿工做于email应用中,造成一个完整的用户体验但每个部分又是相互独立的.正因如此,不一样的应用才能启动这些活动的任意一个(如个email应用容许它).好比,一个照相的应用,能开启一个email应用中写封新邮件的活动,让用户分享一张照片.
    • 一个activity被看成Activity的子类来实现的,在Activities开发指南中,你能够学到更多关于它的使用

Services服务

    • 一个service是长期运行在后台,执行操做的组件,甚至能够为远程进程工做.一个服务不提供用户界面.好比,当用户在其余应用中时,一个服务可能在后台播放音乐,或者在后台获取数据,这并不影响用户跟其余的活动进行交互操做.其余的组件,好比一个activity,能够启动一个服务,并可让它运行或者邦定到这个activity,以便与其进行交互操做.
    • 一个服务是做为Service子类来实现的,在Services开发指南中,你能学到更多关于它的使用

Content providers 内容提供

    • 一个content provider管理共享的应用数据集.你能够把数据存在文件系统中,一个SQLite数据库中,网上,或你应用能够访问的永久存储器中.经过内容提供者,其余的应用能够查询甚至修改数据(若是内容提供者容许的话). 好比,Android系统提供一个内容提供者管理用户通讯录信息.所以,任何拥用适当权限的应用,能够查询内容提供者的部分来(好比ContactsContract.Data)读取和写入关于某我的的信息.内容提供者对于读取和写入属于你的应用的私有的非共享数据也是很是有用的,好比Note Pad样例应用程序,就使用内容提供者来保存笔记的.
    • 一个内容提供者被看成ContentProvider的子类实现,而且必须实现一套标准的APIs,以让其余的应用能执行交换操做。
    • 参考Content Providers开发指南,以了解更多信息.

Broadcast receivers广播接收者

    • 广播接收者是一个响应系统范围广播公告(通知)的组件.许多广播信息,都是来源于系统,好比,通知屏幕关闭的公告,电量低,或抓取了一张图片.应用也能发起广播,好比,让其余的应用知道一些数据已下载到设备了,而且他们可使用了。虽然广播接收者,不能显示用户界面,但当一个广播事件发生时,它们能够建立一个状态通知器,去提醒用户.但更多状况下,一个广播接收者只是一个其余组件,想要作极小量事件的一个"gateway”(途径).举例,它可能发起一个服务,去执行关于某个事件的一些工做.
    • 一个广播接收者,是看成BroadcastReceiver子类被实现的.每一个广播接收者都是从Intent对象衍生出来的。更多信息,请参考BroadcastReceiver类

任何一个应用能启动另外一个其余应用的组件,是Android系统设计独一无二的方面(aspect).好比,你想要用设备的照相机拍一张图片.其余的应用已经有了这个功能,而且你的应用可使用它,而不须要你本身去开发一个拍照相的activity.你并不须要合并(包含)或者甚至是连接camera应中的代码; 而只是,简单的启动camera应用中的活动,来拍照就能够了.当拍照完成,甚至把照片返回给你的应用,因此你能使用它。对于用户来说,camera像是你应用中一部分.当系统开启一个组件时,它会启动那个应用的进程(若是该应用没有运行),并实例化该组件所须要的类.举例,若是你的应用开启一个camera应用的activity,来拍照,这个activity将运行在属于camera应用的进程中,而不是在你的应用的进程中.所以,不像大多数其余的系统的应用,Android应用,没有单个的入点(好比没有main()函数).异步

由于系统运行的每一个应用,在一个带有文件权限的,独立的进程中,这样限制了对其余应用的访问,你的应用不能直接访问其余应用中的组件.但时,Android系统也能激活其余应用的组件.你必须传一个消息给系统,指定你想要启动的组件,而后系统为你激活这个组件.ide

激活组件-Activating Components


4个组件中的其中三个组件---activities,serivces,和broadcast receivers----是被叫作intent的异步消息激活的.在运行时,Intents把某个的组件与其余的组件互相邦定,而无论这个组件是否属于你的应用仍是其余的应用(你能够把它们想像成一个消息,用于请求一个其余组件的动做).

一个intent是一个由Intent建立的对象.该对象定义了一个激活某个特定组件或者某个组件类型的消息,一个intent能够是显示的,一样,也能够是隐式的.

对于activities和services,一个intent(意图)定义了一个要执行的动做(好比:to”view”或"send" 些什么),并指定了要采用的URI格式的数据(其中一些,是其余组件启动所须要知道的).好比,一个intent可能传送一个请求给一个activity,要显示一张图片或打开一个网页.在有些状况,你启动一个activity接收一个结果,这种状况下,activity将在Intent中返回一个结果.(好比,你能够指示一个intent,让用户取一我的的联系方式,并返回给你,返回的intent中会包含一个指向选定联系方式的URI.)

对于广播接收者,intent只是定义了一个作为广播的公告.(好比,一个广播指出,设备电池低,它只是包含了一个动做字串,表示”电池低”).

其余组件,内容提供者,不会被intents所激活.进一步讲,它是内容解释者(ContentResolver)所请求的目标所激活的.内容解释者,处理全部与内容提供者的直接交换.因此组件不须要执行与提供者交换,而是调用ContentResolver对象方法.(这一句很差理解。)为了安全起见,组件请求信息与内容提供者之间有一个抽象层.

下面是激活各类类型组件的几个方法:

  • * 你能够经过传一个(或者一些要作新的事情)Intent参数给startActivity()或startActivityForResult()(当你想要activity返回一个参数)函数(),来启动一个activity.
  • * 你能够传一个Intent给startService()方法,(或给一个新的指令给正在运行的服启),或者你能够传一个Intent给bindService()方法来邦定到服务.
  • * 你能够经过使用sendBroadcast(), sendOrderedBroadcast(), 或者 sendStickyBroadcast()三种方法来广播一个intent。
  • * 你能够对ContentResolver调用query()方法,对内容提供者进行查询

关于使用intents的详细信息,请看Intents and Intent Filters 文档。在后面的文档中,也有一些关于激活某个组件的信息Activities, Services, BroadcastReceiver and Content Providers.

清单文件-The Manifest File


在Android系统开启一个应用组件以前,系统必须经过读取AndroidManifest.xml文件来知道组件的存在.你的应用必须把它全部的组件声明在这个文件中,而且必须在应用工程的根目录下.

这个manifest文件除了声明组件外,还处理了许多其余的事情,好比:

  • * 指定应用请求的其余权限,访问网络或访问用户的通讯录
  • * 声明应用要求的最小API Level,应用使用的是那个API
  • * 声明应用请求和使用的软硬件特征,好比照相机,蓝牙服务,或多点触模屏
  • * 应用须要连接的API库,好比Google Maps library
  • * 等等

声明组件-Declaring components


manifest文件的主要任务是告诉系统,应用的组件,好比,一个manifest能够这样声明一个activity:

1
2
3
4
5
6
7
8
9
<?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>

在 元素中,android:icon指定应用的icon资源
在 元素中的,android:name 属性,指定Activity子类的彻底类名,android:label 属性,为activity指定一个用户能够见的标签。
你必须这样声明 全部应用的组件:

  • 声明活动的元素
  • 声明服务的元素
  • 声明广播接收者元素
  • 声明内容提供者元素

在你代码中包含的,Activites,services和内容提供者,若没有在manifest中声明,对系统来讲是不可见的,即将永远不会运行。可是,广播接收者便可以在manifest中声明,也能够在代码中动态建立(作为BroadcastReceiver对象)而且经过registerReceiver()方法向系统注册。

了解manifest文件的详细构建过程,请看The AndroidManifest.xml File文档

声明组件功能-Declaring component capabilities


就如在上面的Activating Components中所讨论的,你能够用一个Activating Components启动activities,services和broadcast 接收者.你也能够在intent中显式的指定目标组件(使用组件类名)。然而,intent真正强大的是它的intent action.(动做)。经过使用intent动做,你只须简单的描述你要执行的action类型,(而且,可选的与执行动做有关的数据),而且容许系统在设备上找到一个组件,这样就能够执行那个动做并启动它。若是有多个组件能够执行,intent指定的action,那么用户选择执行那一个.

经过比较设备上的其余应用的manifest文件上的intent filters与接收到的intent.系统肯定那个组件能够响应一个intent.
当你在你的应用的manifest中声明一个组件时,你能够可选择包括intent filters(意图过滤器),来指定组件的功能,以让其能响应其余应用的intents.你能够加一个组件声明的元素的子元素,为你组件声明一个意图过滤器。

好比,一个email应用中,新建email的一个activity可能在它的manifest 中声明了一个意图过滤器,以便能响应”send”意图(为了发送邮件)。而后,在你的应用中的一个activity,建立了一个带有”send” ACTION_SEND的意图,.当你调用startActivity()方法,启动该意图过滤器时,系统将其匹配到email应用的“send”活动,并运行它。

关于建立意图过滤器的详细信息,参考Intents and Intent Filters 文档

声明应用需求-Declaring application requirements


有许多设备装了Android,但它们并不提供全部相同的特色和功能.为了不你的应用,装在一个没有你应用所必特征的设备上.经过在你的manifest文件中声明软件硬件要求,明了的指出你的应用支持的硬件类型是很是重要的大多数声明仅仅只是信息,系统并不读取他们,但像Android市场这样的其余服务,将读取它们,以便让用户在为他们的设备寻找应用时,能够进行筛选.

好比,若是你的应用须要有照相机,而且使用的API是2.1(API Level 7),你应在你的manifest文件中声明这些要求.这样,那些没有照相机而且Android版本低于2.1的设备,就不能从Android市场上安装你的应用.

但,你也能够声明你的应用使用camera,但没必要需要求。那种状况,你的应用必在运行时一个检查,以肯定设备是否有一个照相机,若是没有照相机,并禁止与照相相关的功能。

下面是一些重要的设备特性,你在设计和开发应用时必需要考虑的..

    • creen size and density 屏幕尺寸与解释度
  • 为了能从它们的屏幕尺寸来分类设备,Android为每一个设备定义了两个特性:屏幕尺寸(屏幕的物理尺寸)和解释度(在屏上的像素的物理密度,或者dpi--每英寸的点数).为了简化屏幕配置的全部不一样类型,Android系统把它们分红可选的组,以便更容易定位

  • 屏幕大小:小,正常,大和极大

  • 屏幕解释度:低解释度,中解释度,高解释度,和极高解释度

  • 默认状况下,你的应用是兼容全部屏幕尺寸和解释度的,由于Android系统对此作了适当的调整,以使得它适合你的UI布局和图像资源

  • 然而,你应为某个屏幕尺寸建立特殊的布局,并为某些解释度提供特定的图像,使用可选的资源,并在你的manifest文件中用 元素声明,以明确指出你的应用支持的屏幕尺寸.

  • 更多信息,参考Supporting Multiple Screens文档

    • Input configurations 输入配置
  • 许多设备为用提供了一个不一样类型输入装置,好比,硬件键盘,轨迹球,five-way导航pad.若是你的应用必需要一个特别的输入硬件,那么你应在你的应用中使用元素声明.但时,应用必需要一个特别的输入配置的状况是极少的.

    • Device features 设备特性
  • 在一个装有Android的设备中,有许多软硬件特性,有可能有,或有可能没有。好比照相机,光敏器件,蓝牙,或某个版本的OpenGL,或者触模屏的精度.你应该从不假设,在全部的装有Android的设备中某个特色是可用的(除了标准的Android库),因此你应该用 元素声明你的应用支持的特征.

    • Platform Version 平台版本
  • 不一样的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版以后,加入到平台的,你应该用元素,声明最小API级别,这样就指出了那些API将被采用.

为你的应用声明全部必要性的要求很是重要.由于,当你把你的应用发布到Android市场.市场,将用这些声明信息来过滤出,那些应用在每一个设备是可用的. 一样,你的应用应该只能在知足全部你应用需求的设备上才可用.

更多关于Android市场如何基于这些需求过滤的,请看Market Filters文档

应用资源-Application Resources


一个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开发指南

相关文章
相关标签/搜索