Android_Fundamentals_chs_1-3(自译)

Application Fundamentals

app一旦安装到设备上,就存在于独享的安全沙盒中

安卓运行系统为多用户Linux系统,每个App作为一个用户。

默认情况下,系统为每个App分派唯一的Linux用户ID(该ID仅供系统使用,对app本身不可见)。系统为app内所有文件设定权限,以保证只有用户ID指派到的app才能访问这些文件。

每个进程拥有其自身的虚拟机,因此app的代码运行在与其他app隔离的环境下。

默认情况下,每个app运行在其自身的Linux进程中。Android系统在需要app组件需要执行的时候启动该进程,在app不再有使用需求或系统需要为其他app腾出内存时终止该进程。

最小特权原则:
POLP,Principle of least privilege
将访问权限限制到最低水平但仍能保证正常运作的做法。

安卓系统实现该原则,使得在默认情况下每个app只访问工作时所需的组件。这就创造了一种非常安全的环境,使得app不能访问未授权的系统部分。

app与其他app共享数据、app访问系统服务的方法:

为两个app安排相同的Linux用户ID,这种方法可以使这些app互相共享文件。出于节约系统资源的目的,相同用户ID的app运行在同一Linux进程中,并且共享一个虚拟机(这些app必须有同样的证书签名)。

app可以申请访问设备数据的权限,例如用户的联系人、短信、已安装的存储设备(如SD卡)、摄像头、蓝牙组件等。所有app权限必须在安装时由用户授予。

privilege 特权

conserve 保护,保存(强调节约)

be granted by 被授予 grant 授予,承认,同意

App Components

组件为Android app的必要组成部分。每一组件都是app的系统访问接入点。并不是所有组件都是用户实际的访问点,但是每个组件均作为它自身的实体存在,并且扮演着特定的角色——每个组件都是唯一的建筑砌块(组成部分),帮助定义你的app的总体运转状态。

app组件共有四种。每个类型都提供一个特定的(确切的)目标,拥有特定的(确切的)生命周期,该生命周期用于定义该组件如何创建、如何销毁。

Activities

Activity表现为包含用户接口(UI)的单独的屏幕。邮箱APP为例(该示例省略)。尽管这些activities协同工作形成了紧密结合的app用户体验,但是这些activities是相互独立的。因此,不同的app可以启动这些activities中的任意一个(如果邮件app允许)。举例说明,一个摄像app可以启动邮件app内的activity,以便于用户完成分享照片操作。

Activity均作为Activity类的子类实现。

Services

Service为运行在后台的组件,用于执行长期运行的操作,或者执行远程进程的工作。Service不提供UI。举例说明,Service可能在用户访问其他app时在后台播放音乐,或者在不使用activity阻塞用户UI的情况下从网络获取数据。另一组件可以启动service并使其运行或将其绑定至该组件来进行交互。

Service均作为Service类的子类实现。

Content providers

Content providers管理app数据的共享集合,开发者可以在文件系统中、SQLite数据库中、网络端、或者是其他app可访问的持久存储位置存储数据。通过content provider,其他app可以查询甚至是修改这些数据(如果content provider允许)。举例说明,Android系统提供一个content provider用于管理用户联系人信息。因此,拥有合适权限的app便可以查询content provider的一部分来读写某特定联系人的相关信息。

Content provider也常用于读写app私有的不共享的数据。举例,Note Pad示例app使用content provider保存笔记。

Content Provider均作为ContentProvider的子类实现,并且必须实现APIs标准以使其他app能够执行(交互)事务。

Broadcast receivers

Broadcast receivers是响应全系统广播的组件。许多广播由系统发出。举例,通知屏幕关闭、电池电量低、或者图像被捕捉到的广播。app也可以初始化广播,举例,令其他app知晓有数据已下载到设备可供使用。尽管broadcast receivers不显示UI,但是可以在broadcast event(广播事件)发生时,创建一个状态栏通知来提示用户。更加普遍的情况是,broadcast receiver仅仅作为与其他组件相关的“gateway”(入口,网关),规定只做少量工作。比如根据事件Event初始化一个Service完成某些工作。

broadcast receiver均为BroadcastReceiver类的子类的实例,每个broadcast作为Intent类传输(发送)。

Android系统设计具有一个独有的特性,任何app都可以启动另一app的组件。举例,如果用户需要使用摄像头拍一张照片,很可能另一个app已经拥有该功能而你只需要调用它,而不需要重新自己开发一个activity来拍照。开发者不需要混用或链接到摄像头app的代码,仅需简单地启动摄像头app的activity便可。拍照完成时,照片会被传送到你的app以供使用。对于用户来说,看起来摄像头功能就像是app的一部分。

当系统启动组件后,它同时也启动了该app的进程(如果不是运行中)并且将该组件需要的类实例化。举例说明,如果app启动了一个摄像头app的activity拍了照片,那么这个app就运行在属于摄像头app的进程中,而非你的app的进程。也就是说,与其他大多数系统的app不同,Android应用没有单一的进入点(没有主方法)。

由于app运行在系统不同的进程中,使用文件权限设定来限制对其他app的访问,所以你的app不能直接激活其他app的组件,但是Android系统可以做到。因此如果需要激活另一app的组件,开发者必须发送一条消息到系统中,从而指明Intent来启动某个特定的组件。之后Android系统会激活该组件。

Activating Components

四种组件中的三种——activities,services,以及broadcast receivers均由名为Intent的异步消息激活。在运行期间Intents绑定在相互独立的组件上(可视作请求其他组件行动的信使),无论组件属于你的app还是其他app。

intent由Intent对象创建,它定义了用于激活另一特定组件或者一个特定类型组件的消息,intent可以是显式的也可以是隐式的。

对于activities和services来说,intent定义了需要执行的动作(如浏览或发送数据),并且可以区分数据的URI(Uniform Resource Identifier)。举例说明,一个intent能够发出一个请求用于显示一幅图片或打开一个网页。在某些情况下,你可以启动一个activity用来接收结果,这种情况下,activity也会在Intent中返回结果(举例说明,你可以发出一个intent,让用户选择一位个人联系人然后将其结果返回——返回的intent中包含指向该被选中联系人的URI)。

对于broadcast receiver,intent简单地定义了用于广播的声明(通告? 举例说明,用于指出设备电池电量低的广播包含一条已知的动作字符串,指出“电量低”)。

其他组件类型,content provider,不由intents激活。相反,它在作为来自ContentResolver的请求的目标时被激活。Content resolver处理所有涉及到content provider的直接事务,因此与provider配合执行事务的组件并不需要参与其中。(so that the component that’s performing transactions with the provider doesn’t need to),反之,采用调用ContentResolver对象的方法。在content provider和请求信息的组件之间建立了一个抽象层(为安全起见)。

激活不同的组件有不同的方法:

通过向startActivity()或是startActivityForResult()发送Intent来启动activity(or give it something new to do)。需要返回result时使用后者。

通过向startService()发送Intent来启动Service,或者是向运行中的Service传递新的指示。通过向bindService()发送Intent来绑定Service。

通过向类似于sendBroadcast()、sendOrderedBroadcast()、sendStickyBroadcast()的方法传送Intent来初始化broadcast。(sendOrderedBroadcast发送有序广播,对应的所有接收器只能按照一定的优先级顺序,依次接收intent;sendStickyBroadcast发出的最后一个Intent会被保留,下次当Recevier处于活跃的时候,又会接受到它。)

可以调用ContentResolver的query()方法来执行对content provider的查询。

更多Intent相关信息请查看Intents and Intents Filters文档。

The Manifest File

在Android系统能够启动app组件之前,系统必须通过读取app的AndroidManifest.xml文件,以获知组件的存在。App必须在该文件中声明所有组件,该文件必须位于app工程的根目录下。

manifest为声明app的组件做了一系列工作:

定义app需要的用户权限,例如网络访问权限、联系人读取权限。

根据app所使用的APIs,声明该app所需的最小API Level。

声明app所需的硬件及软件特征,如摄像头,蓝牙,多点触控屏幕等。

App所需要链接的API库(非Android框架APIs),如谷歌地图库。

Declaring components

manifest的主要任务:向系统告知app的组件。xml文件为例。

<?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 属性指明用以辨别app的图标的资源文件。

android:name 属性指定了Activity子类的完整类别名称。

android:label 属性指定了一个字符串作为该activity的用户可见标签。

声明全部app组件的方法:

activities

services

broadcast receiver

content providers

包含在source中但未在manifest中声明的Activities,Services,content providers将对于系统不可见,并且无法运行。但是,broadcast receiver可以在manifest中声明也可以在代码中动态创建(BroadcastReceiver对象),并通过registerReceiver()方法注册到系统。

Declaring component capabilities

如上所述,可用Intent启动activities,Service,Broadcast Receivers。可以在Intent中,通过显式地命名目标组件来实现启动(使用组件类名)。但是,Intents的真正能力藏于隐式Intents中(implicit intents)。隐式Intent简单地描述了将要执行动作的类型(也可根据想要执行的动作来选择数据),使得系统能够在设备上找到执行动作的组件并使之启动。如果有多个组件均可以执行该动作,那么用户就选择其一。

在app的manifest中声明activity时,可以选择性地添加Intent filters来声明activity的capabilities(能力,性能),使其能够响应其他app的intents。开发者可以使用组件声明元素的子元素——元素来声明组件的intent filter。

<manifest ... >
    ...
    <application ... >
        <activity android:name="com.example.project.ComposeEmailActivity">
            <intent-filter>
                <action android:name="android.intent.action.SEND" />
                <data android:type="*/*" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>

当另一app创建带有ACTION_SEND动作的intent并发送至startActivity()方法时,系统就能启动你的Activity以供用户起草以及发送邮件。

Declaring app requirements

Android系统支持多种设备,这些设备提供的features和capabilities并不全部相同。为了避免app安装到缺少必备features的设备上,需要开发者在manifest中明确定义出app支持的设备类型以及软件需求。大多数声明仅为说明信息,并不会被系统读取到,但是外部服务例如Google Play,能够读取到这些信息,并且在用户搜索符合设备的app时提供筛选服务。

举例,假设app需要摄像头并且引入了Android 2.1的APIs(API Level 7),开发者应该在manifest中声明这些需求。

<manifest ... >
    <uses-feature android:name="android.hardware.camera.any"
                  android:required="true" />
    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" />
    ...
</manifest>

现在,无摄像头的设备以及Android版本低于2.1的设备便无法从Google Play安装该app。

也可以声明app使用了摄像头,但是并不作为必须的需求。这种情况下,app应该将required属性设置为“false”并且在运行时检查设备是否拥有摄像头,并且在合适的时机将摄像头功能禁用。

App Resources

一款Android app不仅仅由代码组成,还需要与源代码分离的资源,例如图片、动画文件、以及一切与app视觉表现有关的东西。举例说明,开发者应该使用XML文件定义动画、菜单、设计风格、颜色、activities的UI布局。使用app资源文件可以方便地在不修改代码的前提下更新app的各种字符,方法是提供一系列替代资源,这使得开发者能够针对不同的设备配置优化自己的app(例如不同的语言和屏幕尺寸)。

对于包含在Android工程内的每个资源文件,SDK构建工具都为其定义了唯一的整数ID,开发者可在app代码和其他XML文件定义的资源中通过该ID引用到该资源。举例说明,如果app包含一个名为logo.png的图像文件(保存在res/drawable/目录),SDK工具会产生一个名为R.drawable.logo的资源ID,开发者可以引用该ID,从而在UI中插入对应图片。

资源与代码分离的一个重要影响是,开发者可以为不同的设备配置提供可替换的资源文件。举例,使用XML文件定义UI中的字符串,可以将其翻译为其他语言并保存在分类的文件中。之后,基于由开发者添加资源目录名称形成的语言预选器(language qualifier 例如res/values-fr/ 表示法语字符串值)和用户的语言设置,Android系统能够自动适配,将UI中的字符串转换成适当的语言。

Android支持许多用于资源文件替换的qualifier。Qualifier为一个包含在资源文件目录名中的短字符串,用于定义针对不同的设备配置如何选用资源文件。举例,开发者常常需要依据设备屏蔽的方向和尺寸为activities开发多种布局。举例,当屏幕处于肖像(portrait)方向(高模式),开发者或许想要一种按钮垂直放置的布局,当屏幕处于风景画(landscape)方向(宽模式)时,按钮应该安排为水平布置。为了根据方向来改变布局,开发者可以定义两种不同的布局,对于每种布局的目录名应用合适的qualifier。之后,系统就能够根据当前设备的放置方向自动应用合适的布局了。

Tips:

actual 实际的; 真实的; 现行的; 现在的;

overall 总体的,全面的;

behavior 行为; 态度; (机器等的) 运转状态; (事物的) 反应;

distinct 明显的,清楚的; 卓越的,不寻常的; 有区别的; 确切的;

cohesive 有黏着力的; 紧密结合的;

perform 执行; 履行; 表演; 扮演;

content 目录; 容量; 满足

originate 引起; 创始,创作; 开始,发生; 发明; 

gateway 入口; 门; 途径; 

is intended to 规定为,意为

specify 指定; 详述; 提出…的条件; 使具有特性;

asynchronous 异步的

explicit 显式的 明确的,清楚的; 直言的; 详述的; 不隐瞒的; 

implicit 隐式的 不言明[含蓄]的; 无疑问的,绝对的; 成为一部份的; 内含的; 

announcement 宣告; 通告; 布告; 预告;

the fully qualified class name 完整类别名称;

capability 能力,性能;

powered by 运转,由…提供支持;

appropriate adj 适当的; 合适的; 恰当的; v. 盗用; 侵吞; (专款等) 拨;

optimize 使最优化,使尽可能有效;

portrait 肖像画

landscape 风景画

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值