Android 应用程序基础
应用程序基础
Android开发包工具将代码和资源数据文件编译成以.apk后缀的安装文件。单个.apk文件就是一个应用程序,可被用来安装在Android系统的手机上。
一旦安装在设备上之后,每个Android应用程序运行在它自己的安全的沙箱中:
Android操作系统是多用户Linux系统,每个程序是一个不同的用户。
系统会分配每个应用程序一个独立的Linux用户ID(这个ID只会被系统使用,而应用程序是不需要关心的)。系统会使用这个独一无二的用户ID来设置程序文件的权限,所以只有拥有这个用户ID的应用程序才可以访问这些文件。
每个进程运行在自己的虚拟机中,所以应用程序各自互补干扰。
Android系统启动需要的进程,然后关闭不需要的进程。
Android系统实现的是最精简原则。它创建了一个安全的环境,如果没有获得授权,应用程序是无法访问的。
然而,这里有一些方法与其他的应用程序共享数据:
两个应用程序共享同一个Linux用户ID,他俩就可以相互访问对方的文件。为了节省系统资源,相同ID的程序可以运行在相同的Linux进程中并且共享同一个虚拟机(程序必须使用同一签名)
应用程序对设备数据发出申请,例如:联系,短信,SD卡,摄像头,蓝牙,等等。所有的权限在安装的时候被授权
应用程序组件
组件是Android程序最重要的基石。每个组件都有一个不同的入口点。但不是所有组件是用户访问的入口点。这里有四种不同类型的应用组件。每种类型起着不同的作用,有着不同的生命周期
Activities 活动
活动可以由与用户交互的用户界面来代表。例如,邮件应用会有一个显示邮件列表的活动,一个写邮件的活动,一个读邮件的活动。虽然三者一起构成了整个邮件应用程序,但是他们之间又是相互独立存在的。不同的应用程序能够启动任何一个其他程序的活动。例如,摄像头程序可以启动一个邮件的活动去发送分享含有图片的邮件。
Services 服务
服务是一个组件,一直运行在后台执行任务。服务是没有用户界面的。例如,一个运行在后台播放音乐的服务,一个运行在后台从网络上收集数据的服务。
Content providers 内容提供者
内容提供者管理共享的应用数据。你可以把数据存储在文件系统上,SQLite数据中,web,或者任何一个持久化的地方。通过内容提供者,其他应用程序可以查询或者甚至修改本应用程序的数据。我们也可以使用内容提供者来读写程序的隐私数据内容。
Broadcast receivers 广播接收者
广播接收者是一个能够接收系统范围内的广播通知的组件。许多广播消息来源于系统本身,例如,屏幕关闭,电力不足,照片捕获。应用程序也可以发出广播消息,例如,通知其他应用程序某些数据已经下载完成。尽管广播接收者没有用户界面,但是他们也可以在消息到达后,通过状态通知栏提示用户。一般来讲,我们可以将广播接收者比喻为一个网关。它可以在收到某种特定的消息后,开启某项服务。
Android系统构架中有个独一无二的特点就是任何应用程序都能够启动另外一个应用程序的组件。例如,你想在你的程序中增加一个拍照的功能,由于别人已经开发了一个这样拍照的应用,那么你就不需要再重复劳动开发。而且你都不必在你的程序代码中插入引用外部程序的链接,非常简单地就可以启动拍照程序。当拍照结束,这张照片就可以回到你的程序中,然后就可以随你所用。对于用户来讲,这个拍照功能就是这个程序原生的组件。
当系统启动一个组件,一个进程就会被启动,并且相应类的对象会被实例化。例如,如果你的应用开启了一个拍照程序,那么这个活动就是运行在拍照程序进程中,而不是你的应用程序中。因此,不像其他应用程序,Android系统没有一个单一的入口(没有main函数)。
因为应用程序相互之间有访问权限的问题,所以你的应用程序不能直接激活其他应用程序的组件。所以在Android系统中,为了启动另外一个程序组件,你必须发送一个intent消息激活一个特定的组件,系统会帮你处理这个消息完成激活的工作。
激活组件
四种组件类型中有三个是通过叫做intent的一个异步消息激活的,它们分别是活动,服务和广播接收者。在运行过程中,Intent将这些独立的组件绑定在一起。
一个intent消息就是一个Intent的对象实例,它指定了是去激活一个特定的组件还是一种特定类型的组件。
对于活动和服务组件来讲,intent会定义执行的动作,并且可以指定动作所需的数据URI。
对于广播接收者组件来讲,intent只要简单的定义一下通知的内容.
另外一种组件类型,content provider,不是有intent激活的。当contentResolver发出一个请求时,这种组件就会被激活。因为content resolver直接处理content provider的事务操作,所以组件不需要使用intent,而是直接调用ContentResolver对象的方法。这样在content provider和组件之间留了一层抽象层(为了安全)。
这里分别有一些方法是用来激活其组件的:
传递一个Intent对象给startActivity() 或 startActivityForResult() 来启动一个活动
传递一个Intent对象给startService() 来启动一个服务。或者传递一个Intent对象给 bindService() 来绑定一个服务。
传递一个Intent对象给sendBroadcast() , sendOrderedBroadcast() , 或者 sendStickyBroadcast()来发送一个广播。
调用ContentResolver的query()方法在content provider上执行一个查询。
Manifest文件
在系统启动应用程序组件之前,系统必须读取AndroidManifest.xml文件了解有哪些组件存在。这文件位于应用程序的根目录下。
这个文件除了申明应用组件,还可以:
制定应用程序所需的用户权限,例如,网络访问或对用户联系人的访问。
指定最小的API级别
声明软硬件所需的特性,例如:摄像头,蓝牙,多触控屏幕
其他库文件,例如,Google Maps library
等等
声明组件
声明一个活动的例子如下:
-------------------------------------------------------------------------
<?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>
-------------------------------------------------------------------------
在<application>元素中,android:icon属性指向图标资源。
在<activity>元素中,android:name属性制定Activity子类的全类名。Android:label属性为活动指定一个用户可见的文本标签。
<activity> 元素: 活动
<service> 元素: 服务
<receiver> 元素: 广播接收器
<provider> 元素: 内容提供者
活动,服务,内容提供者没有在manifest文件中声明,即使在程序代码中引用了,还是不能正常运行。然而,广播接受者有两种方式选择,既可以声明在manifest中或者动态创建在代码中(像BroadcastReceiver 对象 ),并且调用registerReceiver() 注册在系统中。