Android帮助文档翻译——开发指南(一)应用程序基本原理
来源:互联网 发布:梦里花落知多少诗 编辑:程序博客网 时间:2024/06/05 00:15
交流可加新浪微博:Android开发人
Android应用程序是由JAVA编写的。Android的SDK工具把编写好的应用程序代码连同一些数据和资源编译成一个.apk后缀的Android应用程序包。包含在同一个apk文件里面的所有代码就当成是一个应用程序安装包,并可以在Android设备上进行安装。
安装在Android设备上的每一个应用程序都运行于自己的安全砂箱中:
Android操作系统是一个多用户Linux系统,每一个应用程序就相当于一个不同的用户;
默认情况下,系统会为每一个应用程序分配一个只对系统可见而对程序不可见的Linux用户ID。系统为每一个应用程序包含的所有文件设置权限,以便通过分配给某应用程序的系统用户ID来访问该程序的这些文件;
每一个进程运行在自己的虚拟机上,这样使每一个应用程序都是独立运行;
默认情况下,每一个应用程序运行在自己的Linux进程中。当应用程序的组件需要被执行时,Android系统会开启一个进程,当进程不再需要运行或系统必须为其它应用程序提供内存空间时,Android会关闭这个线程;
这样的话,Android系统实现了最小特权原则。就是说每一个应用程序在默认情况下只能访问用来完成其工作的自身组件。这就创建了一个应用程序在没有得到授权时无法访问系统其它部分的安全环境。
虽然如此,但应用程序还是有一些途径与其它程序共享数据,或访问系统的服务。
可以让两个应用程序共用一个Linux用户ID,在这种情况下,他们就可以相互访问彼此的文件。为了节省系统资源,两个有共同用户ID的应用程序同样能运行在同一个Linux进程中,并共用一个虚拟机,当然这两个应用程序必须用同一个证书注册;
每一个应用程序能够请求访问设备数据的权限,如用户联系人、短信息、可安装存储(如SD卡)、摄像头、蓝牙等等。所有的这些应用程序权限必须由用户在初始化时进行授权。
这里覆盖了关于一个应用怎么存在于系统中的一些基础知识,接下来在这个文档各个章节中将为你介绍以下内容:
1、 在你的应用程序中使用的核心框架组件;
2、 你用来定义组件和应用程序所需设备环境的manifest文件;
3、 资源与代码分离,并允许完全优化针对各种不同配置设备的行为属性(如:针对不同屏幕分辨率@Sam注)。
应用程序组件
应用程序组件是一个Android应用程序必不可少的一部分。每一个组件都是系统能与你的应用程序进行交互的不同点。并不是所有组件都是对直接面向用户的实体,有一些组件依赖于其它组件而存在,但对于每一个组件来说,它都是以作为一个独自的存在实体,并扮演着特定的角色,也就是说,每一个组件都是来定义你的应用程序外部行为的特定组成部分。
在Android里有四大应用程序组件,每一种类型的组件有不同的作用,并拥有不同的生命周期(生命周期即组件从创建到销毁的整个过程)。
下面就是这四种应用程序组件的介绍:
Activity:
Activity就是一个带有用户接口的界面。比如,一个Email应用程序应该包括一个用来显示邮件列表的Activity、一个用来写邮件的Activity和一个用来读邮件的Activity。虽然这些Activity共同组成了一个Emailt程序的用户体验,但他们彼此之间却是互相独立地存在。因此,只要Email应用程序授权的情况下,其它应用程序可以启动这些Activity的任何一个。比如一个照相程序可以通过启动一个Email程序中新建邮件的Activity来分享照片。
每一个activity界面都是继承了Activity类,你可以在开发指南中学习更多关于Activity的知识。
Services(服务)
服务是一个运行在后台的组件,它不提供一些用户接口界面,一般是用于执行相对费时的操作或运行一些远程进程。比如当用户在使用其它应用时,用一个服务在后台播放音乐或在后台获取网络数据而阻塞影响用户的其它操作。其它一些组件(如activity)可以启动一个服务运行在后台或绑定一个服务来与之进行交互。
每一个服务是继承了Service类,你可以在开发指南中学习更多关于服务的知识。
Contentproviders(内容提供器)
内容提供器是用来处理应用程序的一些共享数据。你可以利用系统文件、SQLite数据库、web或一些永久存储设备(如SD卡,@Sam注)来存储数据,以便你的应用程序可以访问使用。其它应用程序可以通过你的应用程序提供的内容提供器(Content provider)查询或甚至修改这些数据(前提是你允许其它程序修改)。比如,Android系统提供了一个管理用户联系人信息的内容提供器(Content provider),因此,其它应用程序只要取得了相应的权限就可以取得诸如
Broadcastreceivers(广播接收器)
广播接收器是一个用来响应系统全局广播事件的组件。大部分的广播都是由系统产生的,比如屏幕关闭、电量低、选中了一张图片。应用程序也可以自己初定义一个广播,比如通知其它应用程序数据已经下载到了设备上,它们可以使用这些数据了。虽然广播接收器不能显示一个用户接口界面,但它可以在接收到广播时,创建一个状态栏通知信息通知用户。尽管如此,更普通的情况下,广播接收器只是一个与其它应用程序对接的出口,并仅仅是做一些很轻量级的操作(广播接收器不能进行费时的重量级操作 @Sam注)。比如,一个广播接收器在接收到某一个广播后启动一个服务去执行其它一些操作(一般是一些相对重量级的费时操作@Sam注)。
一个广播接收器需要继承
Android系统的一个独特设计就是任何应用程序可以启动其它程序的组件,比如,当你想通过设备的摄像头获取一张照片,通常情况下利用其它有照相功能的应用程序去获取,然后你直接使用得到的这张照片数据就行,而不需要自己去开发一个具有照相功能的程序。要实现这样的功能,你也不需要去包含进照相程序的代码或去连接这个照相程序,你只需在代码中简单地打开一个照相程序的activity界面,然后直接使用现有照相程序进行照相,最后把照片返回供你的应用程序使用。在用户看来,这个照相程序就好像你的应用程序的一部分,实际他们是相互独立的两个程序。
当系统启动一个组件时,如果应用程序还没运行,系统会启动一个包含应用程序和组件所需要的类实例进程。比如,当你的应用程序要启动一个照相程序来获取相片,那么系统将启动一个属于照相程序的线程,而不是你的应用程序进程中打开照相程序。因此,Android应用程序并不像其它大多数系统应用程序一样,它没有一个单独的程序入口(比如并不像其它系统应用程序一样有main()函数这样一个入口)。
因为Android系统中每一个应用程序都是独立运行在自己的进程中,并且有访问其它应用程序的文件权限约束,所以你的应用程序不能直接激活另一个应用程序的组件,只有Android系统可以激活。因此,如果需要激活其它程序的组件,你必须向系统发送一个包含你要打开的这个组件信息的意图(Intent),并由系统为你打开这个组件。
激活组件
activities、服务(services)、广播接收器(broadcast receivers)这三大组件都可以通过一个叫意图(Intent)的异步信息来激活。意图(Intent)在运行时为某一个特定的组件绑定了一个其它组件(你可以理解成一个用来请求其它组件动作的消息),这个组件可是属于你的应用程序,也可以不属于你的应用程序(比如上面例子中的照相程序就不属于你的应用程序 @Sam注)。
一个意图(Intent)就是一个Intent对象,它定义了一个需要激活某个组件或某种类型的组件的消息,这个意图(Intent)可以是显式匹配、隐式匹配或respectively。
对于activities和services,一个意图(Intent)定义了需要执行的动作(如“"view" 或 "send"),也可能指定了启动组件需要的数据URI。比如,可以通过一个意图(Intent)去请求一个activity显示一张图片或打开一个网页。在某些情况下,你可以通过一个意图(Intent)去启动一个activity,并接收这个activity返回的包含了结果数据的Intent。比如,你可以发送一个意图(Intent)打开一个联系人列表界面,让用户选择联系人,并接收一个包含了指向用户选中的联系人URI的意图(Intent)。
对于广播接收器,意图(Intent)就只是简单地定义了当前广播的内容,比如,一个表示设备电量低的广播,只需要包括一个已经定义过的可知字符串去表示电量低这个事件就行了。
四大组件的另一个组件——内容提供器(content provider)是不能通过意图来激活的。更确切地说,当有一个来自
下面是激活每一种组件的方法:
1、 激活activity:通过传递一个意图(Intent)给
2、 激活服务(service)或向一个运行中的服务(service)传递指令:通过传递一个意图(Intent)给
3、 可以通过传递一个意图(Intent)给
你可以通过调用
Manifest文件
在Android系统启动应用程序组件前,系统必须通过读取应用程序的AndroidManifest.xml文件(即manifest文件)来明确有哪些组件存在应用程序中。应用程序必须在其工程根目录下创建这样一个包含了所有组件定义的manifest文件。
这个manifest文件定义了各种关于应用程序组件定义的数据,比如:
1、 定义应用程序需要的用户权限,比如访问网络、访问用户联系人;
2、 定义应用程序至少需要的API级别(Level),这个取决于你的应用程序使用的API版本(在Eclipse实际操作中,在创建工程时选择的API版本后面就有这个参数,是一个数字 @Sam注);
3、 定义应用程序需要的软硬件环境,如需要摄像头、蓝牙或多点触控;
4、 应用程序需要连接除了Android框架APIs外的API库,比如GoogleMaps library(这个库虽然也是Google的,但并没有在标准APIs中,所以当使用时,则需要显式连接这个库进来 @Sam注);
5、 还有更多……
定义组件
Manifest的首要任务就是让系统知道当前应用程序的组件信息。例如,可以像下面一样在manifest文件中定义一个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属性是用来为应用程序指定图标资源(即应用程序的图标 @Sam注)。
在<activity>标签中的android:name属性指定了一个完整修饰的类名,这个类是Activity的子类;android:label属性则是指定一个字符串作为对于用户可见activity标签。
你必须按照以下方法来定义应用程序的组件:
1、 用<activity>标签来定义activities
2、 用<service>标签来定义服务(services)
3、 用<receiver>标签来定义广播接收器(broadcast receivers)
4、 用<provider>标签来定义内容提供器(content providers)
如果有一些activities、服务(services)和内容提供器(content providers)包含在你的应用程序源文件中的,但没有在manifest文件中定义,那么这些组件对于系统来说将是不可见,当然它们也永远不会运行。不同的是,广播接收器(broadcast receivers)即可以在manifest文件中定义,也可以代码中作为一个BroadcastReceiver对象动态创建,并通过调用registerReceiver()方法在系统中注册这个广播接收器。
更多关于如何组织manifest文件的介绍,可以参考TheAndroidManifest.xml File文档。
定义组件的性能
正如在“激活组件”一节中所说的,你可以通过传递一个意图(Intent)去启动activities、服务(services)和广播接收器(broadcast receivers)。你可以在意图(Intent)中通过组件的类名显式地指定目标组件。然而,意图(Intent)的真正强大之处是在于意图中有动作(act
系统确定哪一个组件能够对某一个意图(Intent)进行响应的方法是:系统通过比对收到的意图(Intent)和设备上其它应用程序在manifest文件中提供意图过滤器(ntent filters),如果相匹配则调用这个应用程序对收到的意图(Intent)进行响应。
当你在应用程序的manifest中定义一个组件时,在有需要的情况下,你可以选择为你的组件定义一个描述意图能力的意图过滤器,这样它就能够响应其它应用程序的意图(Intent)。定义意图过滤的方法是:在控件标签下增加一个<intent-filter>子标签进行定义。
比如,一个包含了可以编辑新邮件activity的Email程序,可以在它的manifest入口中定义一个意图过滤器来响应“send”意图(它的意思是发送电子邮件)。这样的话,你就可以在你的应用程序中创建一个包含“send”动作的意图(即ACT
定义应用程序对配置的要求
目前支持Android的设备有很多,但这些设备千差万别,并没有统一的性能。为了防止你的应用程序装到了一台无法提供程序所需性能,所以在manifest文件中明确定义你的程序运行所需的软硬件环境是非常有必要的。通常这些定义只仅仅是一些信息性的描述,而且系统是不会去读取它们的。然而当用户在搜索一些针对他们设备的应用程序时,像Android市场这些外部服务会利用这些信息性描述生成一个过滤器去确定程序与用户设备是否匹配。
例如,你在manifest文件中定义了你的应用程序需要摄像头并且使用了Android2.1的API(API Level 7),那些没有摄像头或系统版本低于Android2.1的设备将无法从Android市场上下载安装你的应用程序。
尽管如此,你也可以定义你的应用程序使用了摄像头,但不是必需的。在这种情况下,你就必须在你程序运行时去判断设备是否有摄像头,并在摄像头不可以情况下屏蔽一些使用了摄像头的属性。
以下是一些在设计开发程序时需要考虑的设备重要属性:
1、 屏幕尺寸和密度
为了通过屏幕来区分设备,Android为每一个设备定义了两个属性:一个是屏幕尺寸,即屏幕的物理尺寸(也即我们平常说的3.5寸、4.3寸等等,@Sam注);另一个是屏幕密度,即屏幕像素的物理密度,或称为dpi(每英寸上的像素点数)。为了简化不同屏幕配置类型的区分,Android系统把他们归纳成不同的选择组,这样就可以地去确定屏幕配置类型。
屏幕尺寸分为小、正常、大和超大四种。
屏幕密度分成低密度、中密度、高密度和超高密度四种。
默认情况下,由于Android系统为你的UI布局和图片资源提供了一个合适的校准,因此你的应用程序可以兼容所有的屏幕尺寸和密度。当然你可以用可选布局资源并在你的manifest中用<supports-screens>标签明确指定你的应用程序所支持的屏幕尺寸,来创建针对某些屏幕的专门布局和提供针对某些密度的专门图片。
2、 输入配置
大部分机器提供了不同的用户输入设备,比如键盘、轨迹球和五维按键。如果你的应用程序需要特定的输入设备,那你就需要在manifest中用<uses-configuration>标签指定你所需的输入设备,然而很少有这种需要某种特定输入设备的应用程序。
3、 设备属性
在一个Android驱动的设备中,可能存在很多的软硬件属性,比如摄像头、光感、蓝牙、专门版本的OpenGL或触摸屏的精确度等等。你永远不要假设在Android驱动设备中的某一个属性是有效的(除了Android标准库外),所以你需要在manifest中用
4、 平台版本
不同的Android设备经常使用不同版本Android平台,如有些使用Android 1.6,有些使用Android 2.3。对于每一个后续版本经常是新增了一些前期版本没有的API,因此,为了更明确API的可用性,每一个平台版本都指定了API的级别(Level),如Android 1.0 是API Level 1,而Android 2.3是API Level 9。如果你使用了1.0版本后API,你就必须利用<uses-sdk>标签定义你所用API的至少API级别。
因为你在Android市场发布应用程序后,电子市场需要利用程序里定义的硬件件环境需求去匹配想使用该程序的设备,所以在程序中定义你的应用程序所需的所有配置环境就显得尤为重要。同样的,你的应用程序也只能在符合其配置需求的设备上运行。
应用程序资源
一个Android应用程序远远不只是由代码组成那么简单,它还包括了一些抽离于源代码的必要资源,如图片、声音文件或其它一些与应用程序相关的可视化界面。例如,你可以用XML文件定义一些动画、菜单、样式、颜色和用户交互界面的布局等。使用应用程序资源,你可以通过提供一些替代资源(alternative resources)就可以简便地更新应用程序的各种属性,使得你可以针对不同配置的设备进行相应的优化,如针对不同语言、不同屏幕尺寸的设备。
对于你的Android程序中每一个资源,SDK开发工具会自动为它定义一个唯一的ID,通过这个ID你可以在程序代码中或用XML定义的其它资源文件中关联该ID对应的资源。例如,你的应用程序中包含了一张叫logo.png的图片(它会被保存到res/drawable/路径下),那么SDK开发工具就会自动生成一个名为R.drawable.logo的ID,这样你就可以用这个ID来关联包含进来的图片,然后插入到你的用户交互界面中(UI)。
可用资源文件最重要的作用之一,就是把资源和代码抽离,这样你就可以方便地为不同设备配置提供不同的替代资源。例如,在XML文件中定义用户交互界面(UI)中用到的字符串,你就可以把这些字符串翻译成其它语言,并保存在一个抽离的文件中。系统将会根据你在资源路径中插入的语言修饰符(如保存成res/values-fr/即表示这个文件中的字符串表示法文)和用户机器中语言的设置为程序选择一个合适的用户界面变语言。
Android系统支持很多不同的替代资源修饰符,这个修饰符其实就是一些包含在资源路径中的字符串。通过这个修饰符可以让设备根据不同配置使用不同的资源。另一个例子就是你的程序可能需要根据设备屏幕方向和尺寸的不同使用不同的布局,比如当设备是纵向的你可能需要一个按钮是纵向的布局,当屏幕是横屏时按钮需要是水平对齐,这时你就可以定义两个不同的布局文件,并为它们分别添加合适的修饰,这样系统就会自动根据设备当前的方向选择合适的布局。
- Android帮助文档翻译——开发指南(一)应用程序基本原理
- Android帮助文档翻译——开发指南(一)应用程序基本原理
- Android帮助文档翻译——开发指南(二)Activity
- Android帮助文档翻译——开发指南(三)任务和Back Stack
- Android帮助文档翻译——开发指南(十五)获取用户位置
- Android帮助文档翻译——开发指南(十五)获取用户位置
- Android帮助文档翻译——开发指南(十五)获取用户位置
- Android帮助文档翻译——开发指南(三)任务和Back Stack
- Android帮助文档翻译——开发指南 获取用户位置
- Android中RemoteViews中文帮助文档【安卓翻译一】
- spark官方指南文档翻译(一)
- ExoPlayer开发指南(官方文档翻译)
- PhoneGap API帮助文档翻译—Connection(连接)
- PhoneGap API帮助文档翻译—Contacts(通讯录)
- PhoneGap API帮助文档翻译—Device(设备)
- PhoneGap API帮助文档翻译—Events(事件)
- PhoneGap API帮助文档翻译—File(文件)
- PhoneGap API帮助文档翻译—Geolocation(地理位置)
- 深入分析Android (build/core/*.mk脚本)
- 无需eclipse无需ant,直接在android源码中混淆编译
- udev实现原理
- 关于 LOCAL_SDK_VERSION
- Android帮助文档翻译——开发指南(三)任务和Back Stack
- Android帮助文档翻译——开发指南(一)应用程序基本原理
- PHP -(快上车)- TP3.2 文件下载
- BindService使用方法:
- error LNK2038: 检测到“RuntimeLibrary”的不匹配项的解决办法
- 基于插件开发的Android实现流程
- excel导入
- android短彩信源码解析-短信发送流程
- 短信拦载
- Android Studio提示忽略大小写