从头开始学Android—应用基础知识
Android 应用采用 Java 编程语言编写。Android SDK 工具将您的代码,连同任何数据和资源文件编译到一个 APK: Android 软件包,即带有 .apk
后缀的存档文件中。一个 APK 文件包含 Android 应用的所有内容,它是基于 Android 系统的设备用来安装应用的文件。
那么Android程序是怎么从源码变成可以安装使用的apk的呢
简易版
apk_easy.png 官方版
apk_m.png 详细版
apk_h.pngAPK的打包与安装比较复杂,这里暂时不展开讨论,留待以后单独成文说明,在此简单总结一下基本的流程:
- 利用aapt打包资源文件,生成R.java和编译后的资源
- 处理aidl文件,生成相应java 文件
- 编译工程源代码,生成相应class 文件
- 通过dex工具把class文件转换成dex文件
- 生成apk文件
- 对apk签名
- 对签名后的apk文件进行对齐处理,使apk中所有资源文件距离文件起始偏移为4字节的整数倍,从而在通过内存映射访问apk文件时会更快
安装到设备后,每个 Android 应用都运行在自己的安全沙箱(SandBox)内:
Android扩展了Linux内核安全模型的用户与权限机制,将多用户操作系统的用户隔离机制巧妙地移植为应用程序隔离。在linux中,一个用户标识(UID)识别一个给定用户;在Android上,一个UID则识别一个应用程序。在安装应用程序时向其分配UID(该 ID 仅由系统使用,应用并不知晓)。应用程序在设备上存续期间内,其UID保持不变。仅限用于允许或限制应用程序(而非用户)对设备资源的访问。如此,Android的安全机制与Linux内核的安全模型完美衔接!不同的应用程序分别属于不同的用户,因此,应用程序运行于自己独立的进程空间,每个进程都具有自己的虚拟机 (VM),与UID不同的应用程序自然形成资源隔离,如此便形成了一个操作系统级别的应用程序“沙箱”
Android 系统可以通过沙箱模型实现最小权限原则。也就是说,默认情况下,每个应用都只能访问执行其工作所需的组件,而不能访问其他组件。 这样便营造出一个非常安全的环境,在这个环境中,应用无法访问系统中其未获得权限的部分。
不过,应用仍然可以通过一些途径与其他应用共享数据以及访问系统服务:
- 可以安排两个应用共享同一 Linux 用户 ID,在这种情况下,它们能够相互访问彼此的文件。为了节省系统资源,可以安排具有相同用户 ID 的应用在同一 Linux 进程中运行,并共享同一 VM(应用还必须使用相同的证书签署);
- 应用可以请求访问设备数据(如用户的联系人、短信、可装入存储装置 [SD 卡]、相机、蓝牙等)的权限。所有应用权限都必须由用户在安装时授予。
应用组件
应用组件是 Android 应用的基本构建基块.共有四种不同的应用组件类型。每种类型都服务于不同的目的,其各自都有不同的生命周期。
-
Activity
Activity表示具有用户界面的单一屏幕。譬如一个显示用户信息的Activity。Activity是四大组件中唯一具有界面的组件。
-
Service
Service是一种在后台运行的组件,用户可以执行长时间运行的操作,但是这个长时间也是相对来说的,如果在Service中执行时间过长,也会引起ANR。
-
ContentProvier
ContentProvier 管理一组共享的应用数据。您可以将数据存储在文件系统、SQLite 数据库、Web 上或您的应用可以访问的任何其他永久性存储位置。其他应用可以通过内容提供程序查询数据,甚至修改数据(如果内容提供程序允许)
-
BroadcastReceiver
BroadcastReceiver 是一种用于响应系统范围广播通知的组件。许多广播都是由系统发起的,例如,通知屏幕已关闭、电池电量不足或已拍摄照片的广播。
启动组件
四种组件类型中的三种—Activity、服务和广播接收器,通过名为 Intent的异步消息进行启动。 Intent 会在运行时将各个组件相互绑定(您可以将 Intent 视为从其他组件请求操作的信使),无论组件属于您的应用还是其他应用。
每种类型的组件有不同的启动方法:
- 您可以通过将
Intent
传递到startActivity()
或startActivityForResult()
(当您想让 Activity 返回结果时)来启动 Activity(或为其安排新任务); - 您可以通过将
Intent
传递到startService()
来启动服务(或对执行中的服务下达新指令)。或者,您也可以通过将Intent
传递到bindService()
来绑定到该服务; - 您可以通过将
Intent
传递到sendBroadcast()
、sendOrderedBroadcast()
或sendStickyBroadcast()
等方法来发起广播; - 您可以通过在
ContentResolver
上调用query()
来对内容提供程序执行查询。
清单文件
在 Android 系统启动应用组件之前,系统必须通过读取应用的 AndroidManifest.xml
文件(“清单”文件)确认组件存在。您的应用必须在此文件中声明其所有组件,该文件必须位于应用项目目录的根目录中。
除了声明应用的组件外,清单文件还有许多其他作用,如:
- 确定应用需要的任何用户权限,如互联网访问权限或对用户联系人的读取权限
- 根据应用使用的 API,声明应用所需的最低API 级别
- 声明应用使用或需要的硬件和软件功能,如相机、蓝牙服务或多点触摸屏幕
- 应用需要链接的 API 库(Android 框架 API 除外),如 Google Maps API 库
- 其他功能
应用资源
Android 应用并非只包含代码—它还需要与源代码分离的资源,如图像、音频文件以及任何与应用的视觉呈现有关的内容。Android一般使用XML定义界面布局,对应的资源(如图片)放到对应的资源目录。提供与源代码分离的资源的其中一个最重要优点在于,您可以提供针对不同设备配置的备用资源。