Android apps are written in the Java programming language. The Android SDK tools compile your code—along with any data and resource files—into an APK: an Android package, which is an archive file with an .apk suffix. One APK file contains all the contents of an Android app and is the file that Android-powered devices use to install the app.
Android应用程序是用Java写的。Android SDK工具编译你的代码以及任何数据和资源文件为APK:一个Android包,这是一个以.apk为后缀的存档文件。一个APK文件包含了一个Android应用程序的所有内容,是Android平台的设备应用程序的安装文件。
Once installed on a device, each Android app lives in its own security sandbox:
一旦安装在设备上,每个Android应用程序存在于它自己的安全沙箱中: |
IN THIS DOCUMENTDeclaring component capabilities 在本文档中
|
|
In this way, the Android system implements the principle of least privilege. That is, each app, by default, has access only to the components that it requires to do its work and no more. This creates a very secure environment in which an app cannot access parts of the system for which it is not given permission. 在这种方式中,Android系统实现了最小特权原则。也就是说,每个应用程序,默认情况下,只能访问到它的工作所需要的最少的权限。这将创建一个非常安全地环境:每一个应用程序不能访问系统没有给予它权限的任何一个部分。 However, there are ways for an app to share data with other apps and for an app to access system services: 然而,有办法让一个应用程序与其他应用程序共享数据,一个应用程序可以访问系统服务:
它可以让两个应用程序共享相同的Linux用户ID,在这种情况下,他们能够访问对方的文件。为了节省系统资源,应用程序使用相同的用户ID也可以运行在同一个Linux进程中,并共享相同的VM(并且应用程序也必须使用相同的证书签名)。
That covers the basics regarding how an Android app exists within the system. The rest of this document introduces you to: 这包括关于一个Android应用程序怎样存在于系统中存在的基本知识。本文档的其余部分向您介绍:
资源是独立于应用程序代码的,让你的应用程序,以优雅地行为为各种设备优化配置。
1.1、App Components(应用程序组件)App components are the essential building blocks of an Android app. Each component is a different point through which the system can enter your app. Not all components are actual entry points for the user and some depend on each other, but each one exists as its own entity and plays a specific role—each one is a unique building block that helps define your app's overall behavior. 应用程序组件是一个Android应用程序的基本构造块。每个组件都是一个不同的角度,通过该系统,可以进入你的应用程序。不是所有的组件都是为用户和一些互相依赖的实际的切入点,但每一个都作为一个独立的的实体,扮演着特定的角色——每一个都是一个可以帮助确定您的应用程序的整体行为独特的构建快。
There are four different types of app components. Each type serves a distinct purpose and has a distinct lifecycle that defines how the component is created and destroyed. 有四种不同类型的应用程序组件。每种类型提供不同的目的,并具有明显的定义组件如何被创建和销毁的生命周期。
Here are the four types of app components: 以下是四种类型的应用程序组件: Activity An activity represents a single screen with a user interface. For example, an email app might have one activity that shows a list of new emails, another activity to compose an email, and another activity for reading emails. Although the activities work together to form a cohesive user experience in the email app, each one is independent of the others. As such, a different app can start any one of these activities (if the email app allows it). For example, a camera app can start the activity in the email app that composes new mail, in order for the user to share a picture. 一个Activity表示为单个屏幕的用户界面。比如,一个email应用程序可能用一个Activity显示新的email列表,用另一个Activity去写Activity,并且使用另外的Activity来阅读Email。虽然活动一起形成一个有凝聚力的用户体验的电子邮件应用程序,但是每一个都是相互独立的。同样的,不同的应用程序可以启动这些Activity中的任何一个(如果Email程序允许他这么做)。比如所,一个相机应用为了分享一张照片可以启动一个Email应用中的Activity来创建一个新的Email。 An activity is implemented as a subclass of Activity and you can learn more about it in the Activities developer guide. 你的应用中的Activity应该是继承了Activity的一个子类,如果想要了解更多,可以参照Activities开发指南。 Service A service is a component that runs in the background to perform long-running operations or to perform work for remote processes. A service does not provide a user interface. For example, a service might play music in the background while the user is in a different app, or it might fetch data over the network without blocking user interaction with an activity. Another component, such as an activity, can start the service and let it run or bind to it in order to interact with it. 一个Service是一个运行在后台的、执行耗时操作或者执行跨进程操作的组件。服务没有用户界面。比如所,当用户在其他应用程序的时候,一个服务可能在后台播放音乐或者它可能从网络上读取数据但并不会阻塞用户和Activity交互。另外一个组件,比如一个Activity,为了与Service交互,能够启动服务并且让它运行或者绑定到它。 A service is implemented as a subclass of Service and you can learn more about it in the Services developer guide. 你的应用中的Service应该是继承了Service的一个子类,如果你想了解更多,可以参照Services开发指南。
Content Provider A content provider manages a shared set of app data. You can store the data in the file system, an SQLite database, on the web, or any other persistent storage location your app can access. Through the content provider, other apps can query or even modify the data (if the content provider allows it). For example, the Android system provides a content provider that manages the user's contact information. As such, any app with the proper permissions can query part of the content provider (such as ContactsContract.Data) to read and write information about a particular person. 一个content provider管理一个分享数据的集合。你能够存储数据到文件系统、SQLite数据库、在网络上或者任何其它的你能够访问的持久化存储位置。通过Content Provider,其他应用程序能够查询或者修改数据(如果Content Provider允许它这么做)。比如说,Android系统提供了一个管理用户联系人信息的Content Provider。同样的,任何具有适当权限的应用程序能够查询Content Provider(比如ContactsContract.Data) 去读取或者修改关于特定联系人的信息。 Content providers are also useful for reading and writing data that is private to your app and not shared. For example, the Note Pad sample app uses a content provider to save notes. Content Provider也能够在读取或者写入你的应用的没有共享的私有数据。比如Note Pad 例子应用程序使用Content Provider来保存日记。 A content provider is implemented as a subclass of ContentProvider and must implement a standard set of APIs that enable other apps to perform transactions. For more information, see the Content Providersdeveloper guide. 你的应用中的ContentProvider应该是ContentProvider 的一个子类,并且为了让其他应用程序能够操作事务,必须实现一个标准的API集合。如果您想要得到更多的信息,可以参照Content Providers开发者指南。 Broadcast Receiver A broadcast receiver is a component that responds to system-wide broadcast announcements. Many broadcasts originate from the system—for example, a broadcast announcing that the screen has turned off, the battery is low, or a picture was captured. Apps can also initiate broadcasts—for example, to let other apps know that some data has been downloaded to the device and is available for them to use. Although broadcast receivers don't display a user interface, they may create a status bar notification to alert the user when a broadcast event occurs. More commonly, though, a broadcast receiver is just a "gateway" to other components and is intended to do a very minimal amount of work. For instance, it might initiate a service to perform some work based on the event. broadcast receiver是一个响应系统范围内发布的广播的组件。很多广播是从系统发布出来的——比如,一个广播通知屏幕已经关闭,电池电量低或者相机已经捕获了一张图片。应用程序也能够发出广播——比如,让其他应用程序知道某些数据已经被下载到设备上,可供它们使用。通过broadcast receiver不能够显示一个用户界面,当广播发生的时候,可以通过创建一个状态栏通知提示用户。更常见的是,一个broadcast receiver仅仅是一个为了做一个非常短暂的事情的到其他组件的"网关"。 例如,它可能会启动一个服务来执行基于事件的一些工作。 A broadcast receiver is implemented as a subclass of BroadcastReceiver and each broadcast is delivered as an Intent object. For more information, see the BroadcastReceiver class. 你的应用程序中的一个broadcast receiver是一个继承自BroadcastReceiver的一个子类并且每一个broadcast传第一个Intent 对象。如果您想要获得更多数据,请参考BroadcastReceiver类。
A unique aspect of the Android system design is that any app can start another app's component. For example, if you want the user to capture a photo with the device camera, there's probably another app that does that and your app can use it, instead of developing an activity to capture a photo yourself. You don't need to incorporate or even link to the code from the camera app. Instead, you can simply start the activity in the camera app that captures a photo. When complete, the photo is even returned to your app so you can use it. To the user, it seems as if the camera is actually a part of your app. Android系统设计的一个特殊的层面是任何应用都能够启动其他应用的组件。例如,如果你想用户使用设备的相机去捕获一张图片,有可能您通过其他应用的去这么做,而不是自己开发一个Activity去这么做。你不需要把相机应用的代码放到你的应用中去,而是改为简单的启动相机应用的Activity去获得一张图片。当捕捉完成的时候,这张图片将返回到你的应用中,所以你能够使用它。对于用户来讲,相机就好像是你的应用程序的一部分。 When the system starts a component, it starts the process for that app (if it's not already running) and instantiates the classes needed for the component. For example, if your app starts the activity in the camera app that captures a photo, that activity runs in the process that belongs to the camera app, not in your app's process. Therefore, unlike apps on most other systems, Android apps don't have a single entry point (there's no main() function, for example). 当系统启动一个组建的时候,它开始一个这个应用的进程(如果他没有正在运行),并且实例化这个组件所需要的类。例如说,如果你的应用启动一个Camera应用的Activity去不活一张图片,该Activity属于相机应用的进程中,而不是在你的用用的进程中。因此,不像其他大多数系统的应用程序,Android应用程序没有一个单独的入口点(例如,没有main()函数) Because the system runs each app in a separate process with file permissions that restrict access to other apps, your app cannot directly activate a component from another app. The Android system, however, can. So, to activate a component in another app, you must deliver a message to the system that specifies your intent to start a particular component. The system then activates the component for you. 由于每个应用程序运行在独立于其它应用程序文件权限的系统中,你的呢应用程序不能直接从另一个程序激活一个组件。但是Android系统可以,所以,要激活另一个应用程序的组件,则必须将消息传递到你的Intent所指定的特定组件中,然后系统为你激活那个组件。 1.1.1、Activating Components(激活组件)Three of the four component types—activities, services, and broadcast receivers—are activated by an asynchronous message called an intent. Intents bind individual components to each other at runtime (you can think of them as the messengers that request an action from other components), whether the component belongs to your app or another. 四个组建类型中的三个——Activity、Service、BroadcastReceiver——通过调用一个Intent的异步消息来激活。Intents在运行是绑定多个组件(你可以把它们看作是请求来自其他组件的动作信使),无论这个组件是否属于你的应用。 An intent is created with an Intent object, which defines a message to activate either a specific component or a specific type of component—an intent can be either explicit or implicit, respectively. 一个Intent是一个Intent对象,它定义了一个消息来激活一个特定的组件或特定类型的组件,意图可以是显式的或隐式的。 For activities and services, an intent defines the action to perform (for example, to "view" or "send" something) and may specify the URI of the data to act on (among other things that the component being started might need to know). For example, an intent might convey a request for an activity to show an image or to open a web page. In some cases, you can start an activity to receive a result, in which case, the activity also returns the result in an Intent (for example, you can issue an intent to let the user pick a personal contact and have it returned to you—the return intent includes a URI pointing to the chosen contact). 对于Activity和Service,意图定义了要执行的action(例如,"查看"或"发送"的东西),并且可以指定执行操作的数据的URI(其中包括了正在启动的组件可能需要知道的)。例如,一个意图可能传达给一个Activity显示一个图片或者打开一个网页的请求。在某些情况下,你就可以启动一个Activity来获得的结果,在这种情况下,该Activity也返回结果中的Intent(例如,你可以发出一个意图,让用户选择一个选择联系人,并将它返回给你——返回意图包括一个指向选中的联系人的URI)。 For broadcast receivers, the intent simply defines the announcement being broadcast (for example, a broadcast to indicate the device battery is low includes only a known action string that indicates "battery is low"). 对于广播接收机,intent只是定义正在发出的广播(例如,一个广播表示该设备电池电量低时只包括已知的字符串,表示"电池电量低")。 The other component type, content provider, is not activated by intents. Rather, it is activated when targeted by a request from a ContentResolver. The content resolver handles all direct transactions with the content provider so that the component that's performing transactions with the provider doesn't need to and instead calls methods on the ContentResolver object. This leaves a layer of abstraction between the content provider and the component requesting information (for security). 其他的组件类型,Content Provider不是通过Intent激活的。相反,它是通过一个ContentResolver发起的请求来激活的。Content Resolver处理与content Provider的所有直接的事务,并不需要Content Provider来执行事务,而是调用ContentResolver对象的方法。这是一个在Content Provider和请求信息的组件之间的一个抽象(为了安全性)。 There are separate methods for activating each type of component: 以下是用于激活每种类型的组件不同的方法:
For more information about using intents, see the Intents and Intent Filters document. More information about activating specific components is also provided in the following documents: Activities, Services, 如果您想获得关于使用Intent的更多的信息,请参考Intents and Intent Filters 文档。还提供了下列文件有关激活特定组件的详细信息: Activities, Services,BroadcastReceiver和Content Providers.
1.2、The Manifest File(清单文件)Before the Android system can start an app component, the system must know that the component exists by reading the app's AndroidManifest.xml file (the "manifest" file). Your app must declare all its components in this file, which must be at the root of the app project directory. 在系统能够启动一个应用程序组之前,系统必须能够从应用的AndroidManifest.xml文件知道这个组件存在。你的应用必须在这个文件中声明所有的组件,它必须在应用程序项目的根目录下。 The manifest does a number of things in addition to declaring the app's components, such as: 清单除了声明应用程序的组件之外,还可以做以下这些事情,例如:
1.2.1、Declaring components(声明组件)The primary task of the manifest is to inform the system about the app's components. For example, a manifest file can declare an activity as follows: 清单文件的主要任务是告知系统有关应用程序的组件。比如,清单文件像下面一样声明一个Activity:
In the <application> element, the android:icon attribute points to resources for an icon that identifies the app. 在<application>元素中,android:icon 属性定位的资源用于作为应用程序的图标。 In the <activity> element, the android:name attribute specifies the fully qualified class name of the Activity subclass and the android:label attributes specifies a string to use as the user-visible label for the activity. 在<activity> 元素中,android:name 属性指定了Activity 子类全限定名,android:label 属性指定了一个用户可见的用于整个Activity的字符串。 You must declare all app components this way: 您必须声明所有的应用程序组件是这样的:
Activities, services, and content providers that you include in your source but do not declare in the manifest are not visible to the system and, consequently, can never run. However, broadcast receivers can be either declared in the manifest or created dynamically in code (as BroadcastReceiver objects) and registered with the system by calling registerReceiver(). Activity、Service和Content Provider仅仅包含在你的代码中,但是却没有在Manifest中声明,这对系统来讲是不可见的,因此,它们不能运行。然而,Broadcast Receiver既可以在manifest也可以在代码中动态创建的声明(如 BroadcastReceiver对象),并通过调用 registerReceiver()方法注册到系统。 For more about how to structure the manifest file for your app, see The AndroidManifest.xml Filedocumentation. 欲了解更多有关如何为您的应用程序构建manifest文件,请参阅AndroidManifest.xml 文档。 1.2.2、Declaring component capabilities(声明组件的能力)As discussed above, in Activating Components, you can use an Intent to start activities, services, and broadcast receivers. You can do so by explicitly naming the target component (using the component class name) in the intent. However, the real power of intents lies in the concept of implicit intents. An implicit intent simply describes the type of action to perform (and, optionally, the data upon which you'd like to perform the action) and allows the system to find a component on the device that can perform the action and start it. If there are multiple components that can perform the action described by the intent, then the user selects which one to use. 如上面Activating Components(激活组件)所讨论的,你能够使用Intent 启动Activity、Service和Broadcast Receiver。你可以通过使用显式命名的目标组件(使用组件类名)的intent这么做.然而真正强大的意图是隐式意图的概念。一个隐含的意图只是简单地描述动作的执行(也可选择,当你想要执行的操作时的数据)的类型和允许系统找到可以执行的操作,并启动在设备上的组件。如果有多个组件能够执行指定的Action,将让用户选择使用哪一个应用程序执行。 The way the system identifies the components that can respond to an intent is by comparing the intent received to the intent filters provided in the manifest file of other apps on the device. 系统可以识别意图并对意图做出反应的组件的方法是:通过比较接收到的意图与在设备上的其它应用程序的清单文件中提供意图过滤器。 When you declare an activity in your app's manifest, you can optionally include intent filters that declare the capabilities of the activity so it can respond to intents from other apps. You can declare an intent filter for your component by adding an <intent-filter> element as a child of the component's declaration element. 当你在你的应用程序清单文件中声明一个Activity时候,你能够选择性的包含Intent Filter的能力,让它能够响应从其他应用发送过来的Intent。你能够通过为你组件增加一个<intent-filter>子元素,定义一个Intent filter。 For example, if you've built an email app with an activity for composing a new email, you can declare an intent filter to respond to "send" intents (in order to send a new email) like this: 例如,如果你构建一个Email应用程序的一个Activity用来创建新的email,你能够定义一个Intent filter去响应"send"intent(为了发送一个email),像下面这样:
Then, if another app creates an intent with the ACTION_SEND action and pass it to startActivity(), the system may start your activity so the user can draft and send an email. 然后,如果其他的应用程序创建了一个action为ACTION_SEND 的intent并且通过startActivity()来启动,系统能够启动你的Activity,以便用户可以起草和发送电子邮件。 For more about creating intent filters, see the Intents and Intent Filters document. 更多关于创建intent filter的内容,请参考Intents and Intent Filters文档。 1.2.3、Declaring app requirements (声明应用程序要求)There are a variety of devices powered by Android and not all of them provide the same features and capabilities. In order to prevent your app from being installed on devices that lack features needed by your app, it's important that you clearly define a profile for the types of devices your app supports by declaring device and software requirements in your manifest file. Most of these declarations are informational only and the system does not read them, but external services such as Google Play do read them in order to provide filtering for users when they search for apps from their device. 有多种设备搭载Android,不是所有Android设备都提供相同的功能和能力。为了防止你的应用程序被安装在缺乏必要功能的设备上,这一点很重要,你应该在你的manifest文件中清楚地定义配置设备类型以满足你的应用程序必须的设备和软件要求,。大多数这些声明是仅供参考,系统不会读取它们,但外部服务,如Google Paly务必阅读它们,以提供用户在搜索满足他们设备的应用程序。 For example, if your app requires a camera and uses APIs introduced in Android 2.1 (API Level 7), you should declare these as requirements in your manifest file like this: 例如,如果你的应用程序需要一个摄像头,并使用了Android 2.1(API级别 7),你应该声明以下的内容,在你的manifest文件中:
Now, devices that do not have a camera and have an Android version lower than 2.1 cannot install your app from Google Play. 现在,如果你的设备没有摄像头或者你的Android系统低于2.1,那么你将不能通过Google Paly安装你的应用。 However, you can also declare that your app uses the camera, but does not require it. In that case, your app must set the required attribute to "false" and check at runtime whether the device has a camera and disable any camera features as appropriate. 然而,您也可以定义您的应用使用Camera,但是不是必须使用它。在这种情况下,你的应用必须设置required 属性为"false",并且运行时检查设备是否有一个摄像头,并禁用任何相机功能(如适用) More information about how you can manage your app's compatibility with different devices is provided in the Device Compatibility document. 更多的关于怎样管理不同设备中你的应用程序能力,请参考Device Compatibility文档。 1.3、App Resources (应用程序资源)An Android app is composed of more than just code—it requires resources that are separate from the source code, such as images, audio files, and anything relating to the visual presentation of the app. For example, you should define animations, menus, styles, colors, and the layout of activity user interfaces with XML files. Using app resources makes it easy to update various characteristics of your app without modifying code and—by providing sets of alternative resources—enables you to optimize your app for a variety of device configurations (such as different languages and screen sizes). 一个Android应用程序是由不仅仅是代码——它需要的资源是独立于源代码,如图像,音频文件,以及有关应用程序的视觉呈现任何内容。例如,你应该定义动画,菜单,样式,颜色,以及Activity用户界面的布局的XML文件。使用应用程序资源,可以很容易地更新你的应用程序的各种特性,而无需修改代码——通过提供两套替代资源——使您能够优化你的应用程序,适用于各种设备配置(如不同的语言和屏幕大小)。 For every resource that you include in your Android project, the SDK build tools define a unique integer ID, which you can use to reference the resource from your app code or from other resources defined in XML. For example, if your app contains an image file named logo.png (saved in the res/drawable/ directory), the SDK tools generate a resource ID named R.drawable.logo, which you can use to reference the image and insert it in your user interface. 对于您在您的Android项目包括所有的资源,在SDK编译工具定义一个唯一的整 数ID,你可以用它来 从您的应用程序的代码或从XML中定义的其他资源引用资源。例如,如果您的应用程序包含一个名为映像文件logo.png(保存在res/drawable/目录下),SDK工具生成一个名为资源ID R.drawable.logo,您可以用它来 引用该 图片并将其插入在用户界面中。 One of the most important aspects of providing resources separate from your source code is the ability for you to provide alternative resources for different device configurations. For example, by defining UI strings in XML, you can translate the strings into other languages and save those strings in separate files. Then, based on a language qualifier that you append to the resource directory's name (such as res/values-fr/ for French string values) and the user's language setting, the Android system applies the appropriate language strings to your UI. 其中提供资源从源代码中分离出来的最重要的方面是能够让你为不同的设备配置提供替代资源。例如,通过定义在XML中的UI字符串,可以转换字符串成其他语言,并保存这些字符串在单独的文件。然后,基于语言限定词 ,你附加到资源目录的名称(如res/values-fr/法语字符串值)和用户的语言设置,Android系统应用相应的语言字符串到你的UI。 Android supports many different qualifiers for your alternative resources. The qualifier is a short string that you include in the name of your resource directories in order to define the device configuration for which those resources should be used. As another example, you should often create different layouts for your activities, depending on the device's screen orientation and size. For example, when the device screen is in portrait orientation (tall), you might want a layout with buttons to be vertical, but when the screen is in landscape orientation (wide), the buttons should be aligned horizontally. To change the layout depending on the orientation, you can define two different layouts and apply the appropriate qualifier to each layout's directory name. Then, the system automatically applies the appropriate layout depending on the current device orientation. Android支持多种不同的限定词为你替代资源。限定符是您在资源目录的名称包括以定义的这些资源应该用于设备配置的短字符串。再举一个例子,你应该经常对你的Activity创建不同的布局,这取决于设备的屏幕方向和大小。例如,当设备屏幕处于纵向(高),您可能希望一个有按钮的布局是垂直的,但是当屏幕处于横向(宽),按钮应水平对齐。要更改布局视方向,你可以定义两个不同的布局和应用适当的限定词,以每个版面的目录名。然后,系统将自动应用适当的布局取决于当前设备的方向。 For more about the different kinds of resources you can include in your application and how to create alternative resources for different device configurations, read Providing Resources. 欲了解更多有关可以包括在您的应用程序的不同类型的资源,以及如何创建对于不同设备配置替代资源,阅读Providing Resources. |