无聊起来决定翻译一下这篇,可能不会一字一句对照原文翻译,夹杂了自己的私货。另外,对于重要的名词我决定还是不翻译了,见过太多把专业术语翻译成中文让人摸不着头脑的,保留英语反而好理解。
hello world之后需要知道安卓应用的体系架构。如果我们把android app的搭建过程想象成小时候的积木游戏,那么android的积木( building blocks)就是App components(我把它叫做组件)。App components有以下四类:
Activities 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.
An activity is implemented as a subclass of Activity and you can learn more about it in the Activitiesdeveloper guide.
简单粗暴的理解,眼睛所看到的当前屏幕就是一个activity 。注意每一个activity都是相互独立的。activity就是UI。
A service is implemented as a subclass of Service and you can learn more about it in the Servicesdeveloper guide.
这个在hello world中还没有体验到,不过作为java程序员来说Service的概念早已滚瓜烂熟。
Content providers 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 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.
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.
这玩意用来管理你的app中一系列的共享数据。你可以在文件系统,sqllite数据库,web或者任何你的app能够访问的持久化存储位置中存储你的数据。通过Content providers,其它的app们可以查询甚至修改这些数据(只要Content providers允许)。比如android 系统提供了一个管理用户联系人信息的Content provider,那么任何拥有相应权限的app就可以通过查询Content provider的一部分来达到读写某个人信息的目的。
Content providers同样适用于读写你app的私有数据。比如记事本app那个例子里就用它来保存笔记。
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 用来接收全系统范围内的的broadcast 通告,有很多broadcast来源于系统本身,比如关掉屏幕,电池电量过低,或者拍照的时候就会发布broadcast。app也可以产生broadcasts,比如让其他app知道某些可用数据已经下载完成。尽管broadcast reciever没有扮演UI的角色,但是当发生broadcast事件时它可以创建状态通知栏来提醒用户(就是那个屏幕左上角下拉出来的东东吧大概)。
然而更常见的用法是把broadcast receiver当做其它组件的网关(gateway),只用来干一些很简单的工作。比如,可以用它来初始化一个service以执行一些与这个事件有关的工作。
所有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.
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 nomain() function, for example).
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.
安卓系统设计中一个独特的地方在于一切app都可以启动其它app的组件。举例,如果你想让用户用摄像头拍照,那么你可以让你的app调用那些可以拍照的app,而不是自己写一个用于拍照的activity。你无需内置甚至代码链接至相机app。你只需要简单地启动相机app中拍照的那个activity就可以鸟。当拍照完成后,照片会返回给你的app以便你使用。在用户看来这就好像你的app有拍照功能一样。
当系统启动一个组件时,系统为该app启动一个进程(如果这个app还没有运行)并实例化这个组件所需的一系列类。举例,如果你的app启动了相机app的一个拍照activity,这个activity在相机app的进程中运行,而不是在你的app的进程中运行。因此,不像其它大多数系统的app,安卓的app没有一个单一入口。(比如没有main())。
由于系统在具备文件访问权限的进程中运行app,因此限制了app之间的相互访问。你的app不能直接激活另一个app的组件。然而android 系统本身却可以做到这样。所以为了激活其它app的组件,你必须向系统发送一个消息,这个消息指定了你想要启动一个特定组件的意图。然后系统就会为你激活那个组件。
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.
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.
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).
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").
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).
There are separate methods for activating each type of component:
Intent
to startActivity()
orstartActivityForResult()
(when you want the activity to return a result).Intent
tostartService()
. Or you can bind to the service by passing an Intent
to bindService()
.Intent
to methods like sendBroadcast()
, sendOrderedBroadcast()
, orsendStickyBroadcast()
.query()
on a ContentResolver
. 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,BroadcastReceiver
and Content Providers.
activities, services, and broadcast receivers被一个叫intent的异步消息激活。intent在运行时绑定各个相互独立的组件(你可以把intent看做是那些请求某个动作的组件的信使),无论组件是否属于你的app。
创建一个Intent对象就是intent啦,它定义了一个用来激活特定组件或者特定类型组件的消息--intent可以是模糊的,也可以是精确的。
对于activity和service,intent定义了要执行的动作(比如查看或者发送些什么东东)或者指定了一个要用来加载待处理数据的URI。比如intent可以向activity发出一个request以加载图片或者打开一个web页面。有时候,你可以启动一个activity来接收处理结果,此时activity也用intent来返回结果(比如你可以发出一个让用户选择个人联系方式的intent,并且把结果返回给你。而返回结果是一个包含了指向被选定的联系方式的URI的intent)。
对于 broadcast receivers而言,intent只是简单的定义了要广播的通告(比如电池电量过低,也就是一个能被理解的字符串而已)。
至于content provider,它是不会被intent激活滴,而是 当被ContentResolver
发出的请求指定时,它才会激活。 content resolver用content provider 来处理所有的直接transaction,这样子对于与content provider执行transaction的组件来说只需要调用ContentResolver
对象里的方法就行了。This leaves a layer of abstraction between the content provider and the component requesting information (for security).懒得翻译了。