这是第一篇翻译,写在前面
翻译的文章是从官网搬过来的,但是不是逐行逐字的翻译,大概意思说明白说清楚了就行,有些段落的意思类似,我就不重复累赘的描述了
另,翻译水平有限,还请各位大大不要批斗,只是自己学习为提高技术进行的小小翻译
Android应用是用Java语言来写的,Android SDK tools可以编译你的代码(APK文件的形式)。一个APK文件包含一个Android App和android设备安装该APP所需要的文件。一旦安装成功,每一个Android app都存在在各自的安全沙箱中(security sandbox):
☆ Android操作系统是一个多用户Linux系统,每一个app都是一个不同的用户
☆ 默认情况下,系统会给每一个app指定一个独特的Linux user ID(该ID只能被系统分配且app对该ID不可知),系统会利用该指定ID对app的所有文件设置许可(permission),也只能通过这个ID才能访问这些文件
☆ 每一个progress都有自己的虚拟机(virtual machine, VM),所以每个app都区别与其他的app,独自运行
☆ 默认情况下,每一个App都在自己的Linux process下运行。Android在app的组件需要执行的情况下开启progress(线程?),在不需要该app或者系统需要回收内存的时候关闭progress
即在默认情况下,每个app只能访问它运行需要的组件,不能访问系统的其他部分(系统没有给出许可)这个举措创造了非常安全的环境。
然而,通过系统的服务一个app还是有很多方式与其他的app共享数据的。
☆ 可以让两个app共享他们的Linux user ID,这样他们就可以访问对方的文件。为了保护系统资源,拥有相同Linux user ID的多个app会在相同的Linux progress下运行,共享同一个虚拟机(这些app必须使用相同的签名)
☆ 一个app可以通过用户结束的方式要求获得设备中的资料,包括短信(SMS message),安装存储(SD card),照相机,蓝牙和其他。所有的许可必须在安装app的时候获得
App Components
有四种不同的app组件,每一种都服务于不同的目的也有不同的生命周期。每种组件都具有其独特的功能,有些可能会相互依赖。
★ Activities
一个Activity代表一个单独的screen,每一个activity都独立于其他的activity。一个app可以启动另一个app的任何activity(如果允许的话),例如一个camera app可以在email app中被启动,使得用户可以选择照片或者拍照
★ Service
Service是一个在后台执行的组件,可以执行长时间操作或者远程处理。Service不提供用户界面。例如,一个service可以在后台播放音乐同时用户在使用别的app,或者在不阻塞用户界面的情况下从网络上获取数据。Activity可以启动一个service,或者可以绑定一个service以便与service进行交互
★ Content providers(内容供应者?)
内容供应者管理共享的应用程序数据,你可以将数据存储在文件,SQLite数据库,网络或者你的程序可以访问到的任何能够持久存储的地方。通过内容提供者,其他app可以查询甚至修改这些数据(在被允许的情况下)。例如,android系统提供一个内容提供者(ContactsContract.Data)来管理用户的联系信息。任何获得相应允许的app可以查询,读写用户的联系人信息。
内容提供者必须实现ContentProvider并且实现标准的API
★ Broadcast receivers(广播接收器)
广播接收器可以对系统范围内的广播公告做出响应。许多广播都来源于系统——例如,一个广播宣布屏幕将倒转,电量低,或者一张照片被捕获。App也可以发布广播——例如让其他app知道一些数据已经被成功下载。尽管广播接收器并不出现在用户界面上,它仍然会创建一个状态栏通知提醒用户发生了广播事件。用户可以点击通知启动service或者activity。每个广播接收器都必须实现BroadcastReceiver类,同时使用Intent来传递数据。
当系统开启一个组件的时候,它也为这个app启动progress,实例化该组件需要的类。例如,你的app启动了照相机app中的activity来拍照,则该activity在照相机的app的progress下运行,而不在你自己的app的progress中运行。和大部分其他的系统不同,android app并不只有一个入口(没有main()程序)
Activating Components
三种组件(activity, service, broadcast receiver)可以被一种叫做Intent的异步信息激活。一个Intent可以是显式的,也可以是隐式的。
对于activity和service来说,intent传送数据让他们展示出来(例如启动一个新的activity所需要的数据),或者传递url地址打开一个web页面。一些情况下,你可以启动一个activity获得结果,而在另一些情况下activity也可以通过intent传回结果。(例如,你可以发起一个intent让用户选择然后再返回用户选择的数据给你)
而对于broadcast receiver来说,intent只是简单的定义被广播的信息。
另一个组件content provider并不能被intent 激活,它会被来自ContentResolver(内容解析器)的请求所激活。内容解析器处理所有与内容提供者的信息交互,不需要创建内容解析器的实例调用其方法来处理信息交互。
下面有几种方法来激活不同的组件
● Activity
启动activity可以用过传递intent,启动startActivity()/startActivityForResult()
● Service
启动service可以通过startService(),bindService()用于绑定service
● Broadcast
初始化broadcast可以通过传递intent到方法 sendBroadcast()/sendOrderedBroadcast()/ sendStickyBroadcast()
● Contentprovider
使用ContentResolver的query() 方法可以查询content provider
The Manifest File
在android系统启动app组件之前,系统通过app的AndroidManifest.xml文件确认组件是否存在。该manifest(清单)必须放在app项目的根目录下,它声明了app的所有组件:
☆ 声明app需要的用户许可,例如互联网接入许可,读入用户联系人许可等。
☆ 声明app需要的最低版本的API
☆ 声明app需要的硬件和软件需求,例如相机,蓝牙,多点触控屏等
☆ 声明app除了android框架API外需要连接的API库,例如Google Maps Library
☆ 更多….
清单文件如下声明components:
<?xmlversion=”1.0” encoding=”utf-8”?>
<manifest>
<application android:icon=”@drawable/app_icon.png”….>
<activity android:name=”com.example.project.ExcampleActivity”
android:label=”@string/example_lable”…>
</activity>
…
</application>
</manifest>
<activity>声明activity
<service>声明service
<receiver>声明broadcast receiver
<provider>声明content provider
其中,broadcast receiver可以在manifest中声明,也可以在代码中动态的生成(BroadcastReceiver实例),通过registerReceiver()调用
Declaring component capabilities
Intent真正的功能隐藏在隐式intent中。一个隐式的intent可以简单描述执行action的形式(也可以让用户选择),同时允许系统找到设备上的相应组件并启动它。如果设备上有多个符合条件的组件,则由用户选择其中一个启动。
系统识别组件并对发送请求的intent产生响应是基于app的manifest文件中intent-filter。当你在manifest文件中描述一个activity的时候,你可以将intent-filter随意的包含在activity的描述中,这样这个activity可以对其他的apps产生响应。
例如,在一个邮件的app中,新建email的时候,你必须描述一个intent-falter对“send”功能的intent响应,如下
<manifest…>
<application…>
<activity android:name=”com.example.project.ComposeEmailActivity”>
<intent-filter>
<actionandroid:name=”android.intent.action.SEND”/>
<data android:type=”*/*”/>
<categoryandroid:name=”android.intent.category.DEFAULT”/>
</intent-filter>
</activity>
</application>
</manifest>
然后,如果别的app创建了一个带有ACTION_SEND action的intent同时传递给startActivity()方法,则系统会启动你的activity且用户可以编辑和发送邮件。
Declaring app requirements
现在有很多android系统的设备,但是他们并不一定具有相同的功能和特征。为了避免app安装在缺少某些你的app必备特征的设备上,在你的manifest文件中描述清楚app需要的软件环境和设备要求很重要。大部分描述只是信息且系统并不阅读它们,但是一些特别的设备除外,就像Google Play会阅读这些文件,这样用户在设备上搜索app的时候可以提供过滤器。
例如,如果你的app需要相机的支持,还需要在Android2.1平台中引入的API7,你可以在manifest文件中如下描述:
<manifest…>
<uses-feature android:name=”android.hardware.camera.any”
android: required=”true”/>
<uses-sdk android: minSdkVersion=”7” android: targetSdkVersion=”19”/>
</manifest>
这样,没有相机,同时比Android2.1版本更低的设备不能从Google Play上下载并安装该应用。如果required属性设置为false,则不在下载安装的时候检查是否具有相机,而是在使用该app的时候才检查设备是否具有相机功能。
App Resources
一个Android app不仅仅由代码组成,它还需要各样的资源,包括图片,视频文件还有任何相关视觉呈现的东西。例如,你需要用xml文件定义动画(animation),菜单(menu),样式(style),颜色(color)以及activity用户界面布局。使用app的资源使得app更容易升级和维护,同时也使得你的app适应不同的设备(例如不同分辨率的设备使用不同的app资源)。
对于app中使用的每一个资源,SDK build tools会声明一个独特的整数ID,这样你可以在代码中或者在xml文件中通过ID该资源。例如,app中有一张叫做logo.png的图片(保存在res/drawable 目录下),SDK tools会生成一个资源ID(resource ID)叫做R.drawable.logo,然后你可以在代码或者xml文件中通过ID来调用该资源。
资源和代码的分离最重要的一个方面是你可以对不同的设备提供可选择的资源。例如,在xml中定义的UI的string,你可以将这个string转换为其他的语言并保存在别的文件内。然后通过添加在文件夹上的语言限定符(language qualifier)(例如res/values-fr代表的是法语)和用户的语言设置,android系统可以为你的UI提供不同的string。
Android为你的可选择资源提供许多不同的标示符。标示符(qualifier)是被使用在资源目录上的很短的string,可以定义设备系统使用那些资源。另外一个例子是你根据设备的屏幕大小和分辨率为你的activity创建不同的布局。当设备是竖屏(portrait)的时候,你希望你的按钮是垂直布局(vertical),而当你的屏幕是横屏(landscape)的时候,你希望你的按钮是水平布局(horizontal)的。根据屏幕方向(orientation)来布局,你需要定义两个不同布局,放在对应的标示符布局文件夹内。然后系统可以自动根据当前的屏幕方向应用相应的布局。