标签:android
Android 应用是基于Java程序语言的。Android SDK 工具编译你的代码以及任何数据和资源文件到一个APK(全称“an Android package”),那是一个.apk
后缀的归档文件。一个APK 文件包含Android应用所需的所有内容 ,apk文件是Android设备的应用程序的安装文件。
一旦安装在设备上,每个Android应用程序都存在于它自己的安全沙箱:
这样,Android系统实现了最细粒度的权限原则。在默认情况下,每个应用程序只能使用自己能访问的组件来做它需要做的工作。这将创建一个非常安全的环境,应用程序不能访问它没有权限的系统部分。
然而,应用程序与其他应用程序之间以及一个应用程序与系统服务之间,可以有这样的数据共享方式:
本文档主要介绍一个Android应用程序的基础知识。文档其他部分会介绍:
应用程序组件是一个Android应用程序的基本构造块。每个组件都是一个不同的点,通过这个点可以从系统进入你的应用程序。不是所有的组件都是一个实际的切入点,但每一个存在的实体,扮演着特定的角色,每一个都是独特的构建块,能让你规定你的应用程序的整体行为。
有四种不同类型的应用程序组件。每个类型都有不同的目的,有不同的生命周期,有不同的创建和销毁规则。
这里有四种类型的应用程序组件:
每一个Activity都是实现 Activity
的子类,你可以学习更多关于Activities的开发指南。
ContactsContract.Data
)来读取和写入一个特定的联系人信息。
ContentProvider也可用于读取和写入你自己应用程序私有而不是共享的数据。例如,记事本示例应用程序使用ContentProvider保存笔记。
每一个ContentProvider都是实现 ContentProvider
的子类,你可以学习更多关于 Content
Providers 的开发指南。
每一个BroadcastReceivers都是实现BroadcastReceiver
的子类,每个广播作为一个Intent
对象传递的实现。更多信息参见BroadcastReceiver
类。
Android系统的一个独特的方面是任何应用程序可以启动另一个应用程序的组件。例如,如果你想让用户用照相机拍一张照片,可能有另一个应用程序需要使用它,代替应用程序自己开发一个Activity用来拍摄照片。你不需要包含或者连接到相机的应用程序代码。相反,你可以简单的启动一个Activity,在相机拍摄照片的活动完成时可以获得照片,照片会返回到你的应用程序,所以你可以使用它。对用户来说,相机就好像是你的应用程序的一部分。
当系统启动一个组件,它会首先启动应用进程(如果它不是已经在运行)和实例化该组件所需要的类。例如,如果你的应用程序启动相机应用程序拍摄照片的Activity,这些Activity是属于摄像头应用程序的程序,而不是在你的应用程序的程序。因此,不像很多其他系统上的应用程序,Android应用程序没有一个单一的入口点(没有main()函数)。
因为系统运行每个应用程序在一个单独的进程,并限制其他应用程序访问该应用程序的文件,你的应用程序不能直接激活另一个应用程序的组件。不过在Android系统中,如果你的应用程序要激活另一个应用程序的组件,你必须向系统发送一条消息,指定你的Intent来启动某个组件,然后系统为你激活那个应用程序的组件。
三四种类型的组件如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对象的方法。这就留下一个内容提供者和组件请求信息之间的抽象(安全)层。
这是分别激活每种组件的方法:
startActivity()
或者startActivityForResult()
(当你想要Activity返回结果)。bindService()
。sendBroadcast()
,sendOrderedBroadcast()
,
or sendStickyBroadcast()
发起广播。ContentResolver
的 query()
去查询ContentProvider提供的数据查询。
Activities, Services,BroadcastReceiver
和 Content
Providers.关于使用Intent的更多信息,请参见 Intents 和 Intent Filters 文档。关于激活特定组件的更多信息也被提供在以下文档: Activities, Services,BroadcastReceiver
和 Content
Providers。
在Android系统启动一个应用程序组件之前,系统必须通过阅读程序的AndroidManifest.xml
文件知道组件的存在。你的应用程序必须在这个文件中声明的所有组件,它必须在应用程序项目的根目录。
清单除了声明应用程序的组件,还做一些其他的事情,如:
清单的首要任务是告诉系统应用程序中有哪些组件。例如,清单文件可以声明一个Activity,如下:
<span class="pun" style="color: rgb(102, 102, 0);"><?</span><span class="pln" style="color: rgb(0, 0, 0);">xml version</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="str" style="color: rgb(136, 0, 0);">"1.0"</span><span class="pln" style="color: rgb(0, 0, 0);"> encoding</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="str" style="color: rgb(136, 0, 0);">"utf-8"</span><span class="pun" style="color: rgb(102, 102, 0);">?></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"><manifest</span><span class="pln" style="color: rgb(0, 0, 0);"> ... </span><span class="tag" style="color: rgb(0, 0, 136);">></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"><application</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:icon</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"@drawable/app_icon.png"</span><span class="pln" style="color: rgb(0, 0, 0);"> ... </span><span class="tag" style="color: rgb(0, 0, 136);">></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"><activity</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:name</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"com.example.project.ExampleActivity"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:label</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"@string/example_label"</span><span class="pln" style="color: rgb(0, 0, 0);"> ... </span><span class="tag" style="color: rgb(0, 0, 136);">></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"></activity></span><span class="pln" style="color: rgb(0, 0, 0);"> ... </span><span class="tag" style="color: rgb(0, 0, 136);"></application></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"></manifest></span>
在 <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 文档。
如上所述,在 Activating组件 中,你可以用一个Intent来启动Activity,Service和BroadcastRecaiver。你可以使用显式地指定目标组件(使用组件类的名称)的Intent。然而,Intent真正牛逼的地方在于隐式的Intent。一个隐式Intent简单描叙动作类型并执行(并且你可以执行任意你想要的动作),隐式的Intent允许系统在设备上查找相匹配的组件并启动它。如果匹配到多个组件可以执行Intent所描述的动作,那么就会让用户选择使用哪一个。
这种系统能识别可响应Intent的组件,是通过比较Intent在其他应用程序的清单文件提供的Intent过滤器来获得的。
当你声明一个Activity在你的应用程序清单中,你可以包含Intent过滤器来申明Activity的能力,所以它可以响应来自其他应用程序的Intent。你可以通过为组件添加一个 <intent-filter>
元素,作为组件声明元素的子元素,用来定义一个Intent过滤器。
例如,如果你有一个在写新邮件的Activity需要调用一个电子邮件应用程序,你可以定义一个Intent过滤器来响应“发送”的Intent(为了发送新邮件)像这样:
<span class="tag" style="color: rgb(0, 0, 136);"><manifest</span><span class="pln" style="color: rgb(0, 0, 0);"> ... </span><span class="tag" style="color: rgb(0, 0, 136);">></span><span class="pln" style="color: rgb(0, 0, 0);"> ... </span><span class="tag" style="color: rgb(0, 0, 136);"><application</span><span class="pln" style="color: rgb(0, 0, 0);"> ... </span><span class="tag" style="color: rgb(0, 0, 136);">></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"><activity</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:name</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"com.example.project.ComposeEmailActivity"</span><span class="tag" style="color: rgb(0, 0, 136);">></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"><intent-filter></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"><action</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:name</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"android.intent.action.SEND"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);">/></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"><data</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:type</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"*/*"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);">/></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"><category</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:name</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"android.intent.category.DEFAULT"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);">/></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"></intent-filter></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"></activity></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"></application></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"></manifest></span>
然后,如果另一个应用程序创建 ACTION_SEND
Intent并且通过它 startActivity()
,那么系统可以启动你的Activity,用户可以起草和发送电子邮件。
更多关于创造Intent过滤器,请参考 Intents and Intent Filters 文档。
有各种各样的机器设备,他们不能提供所有功能和能力。为了防止你的应用程序被安装在一个“缺少你必须需要的功能”的设备上,重要步骤是你必须在清单文件中明确定义一些配置来表明哪些类型的设备才能支持你应用。大多数的这些声明仅仅只是信息,系统不读它们,但外部服务如Google Play(谷歌应用商店)在排序和过滤用户搜索时,会在他们的设备上阅读应用程序的这些申明。
例如,如果你的应用需要一个摄像头和使用Android2.1的API(API Level 7),你应该在你的清单文件中声明这些要求这样:
<span class="tag" style="color: rgb(0, 0, 136);"><manifest</span><span class="pln" style="color: rgb(0, 0, 0);"> ... </span><span class="tag" style="color: rgb(0, 0, 136);">></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"><uses-feature</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:name</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"android.hardware.camera.any"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:required</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"true"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);">/></span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);"><uses-sdk</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:minSdkVersion</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"7"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="atn" style="color: rgb(136, 34, 136);">android:targetSdkVersion</span><span class="pun" style="color: rgb(102, 102, 0);">=</span><span class="atv" style="color: rgb(136, 0, 0);">"19"</span><span class="pln" style="color: rgb(0, 0, 0);"> </span><span class="tag" style="color: rgb(0, 0, 136);">/></span><span class="pln" style="color: rgb(0, 0, 0);"> ... </span><span class="tag" style="color: rgb(0, 0, 136);"></manifest></span>
现在,没有一个相机和一个Android版本低于2.1的设备无法从Google Play(谷歌应用商店)安装你的应用程序。
然而,你也可以声明你的应用程序使用相机,但不是必须需要它。在这种情况下,你的应用程序必须设置需要的属性 required
为 "false"
,并在运行时设备是否有一个摄像头和禁用任何相机的时候适当的检查。
更多的信息关于如何管理应用程序在不同设备的兼容性请参考Device Compatibility 文档。
一个Android应用程序不仅仅是代码组成的,它需要与源代码分离的资源,如图像,音频文件,以及任何与该应用程序的视觉呈现。例如,你应该定义动画,菜单,款式,颜色,以及用户界面的布局XML文件。使用应用程序资源,可以很容易地更新你的应用程序的各种特性,而无需修改代码,通过提供替代资源集使您可以为不同的设备配置优化你的应用程序(如不同的语言和屏幕大小)。
对于你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创建不同的布局,根据设备的屏幕方向和大小。例如,当设备屏幕是纵向的(高),你可能会想要一个有按钮的布局是垂直的,但当屏幕是横向的(宽),按钮应水平对齐。根据方向改变布局,你可以定义两个不同的布局和应用适当的限定词在布局的目录名。然后,系统自动使用适当的布局会取决于当前设备的方向。
更多关于不同种类的资源,你可以在你的应用程序以及如何为不同的设备配置,创造替代资源,请阅读 Providing Resources。
标签:android
原文地址:http://blog.csdn.net/u012643122/article/details/46467711