前言
作为一个有半年余Android Developing折腾经验的Android Developer(为什么不说“开发经验”呢?因为我仔细想了想,我还没有独立地做出一个完善美观且有使用价值的应用。),要系统地学习安卓平台的基本开发技能,那么第一步,了解并熟识Android的基本世界观,应该就是十分必要的了。以前这方面的知识体系不成系统,比较破碎零散,故借此文稍作整理。
我认为在进入任何一个比较复杂的知识技能体系之前,都需要先用基本世界观来热热身。对于高中物理而言,初中数学物理知识就形成了基本世界观;对于近体诗写作而言,平水韵和对仗的修辞手法就是基本世界观;而对于Android,基本世界观则包括了Android系统的简介、四大组件的含义、以及其他一些基本的开发逻辑。
Android系统
历史与现状
Android(Android System),是一个基于Linux内核的开源移动操作系统,由Google旗下的Open Handset Alliance(OHA,开放手持设备联盟)持续领导与开发,主要设计用于触屏移动设备,如智能手机和平板电脑等。Android 1.0 beta于2007年11月5日问世,至于世界上第一部真正意义上使用Android操作系统的设备,则是2008年10月22日发布的HTC Dream。Android系统采用Linux宏内核,系统核心语言是C和C++,主要的编程开发语言是Java。截止2016年初,Android的最新版本是Android 6.0“Marshmallow”(棉花糖)。
系统与系统架构
Android系统执行于Linux kernel之上,但并不是GNU/Linux。实际上,Android大都并不支持GNU/Linux的一些功能。除了基于Linux的核心之外,则是中介层、数据库元和用C/C++编写的API以及应用程序框架。Android的系统架构如下图所示——
可见,系统架构大致分为四层:Linux内核层,核心库层(以及运行环境),应用框架层和应用层。
Linux内核层比较底层,通常也是对Developer隐藏的。
Android Runtime与Libraries层:
Android的应用程序通常以Java为基础编写,运行程序时,应用程序的代码会被即时转变为Dalvik dex-code(Dalvik Executable),然后Android操作系统通过使用即时编译的Dalvik虚拟机来将其运行。也就是说,Android应用程序是运行在Dalvik虚拟机里面的,并且每一个应用程序对应有一个单独的Dalvik虚拟机实例(这也保证了如果一个Android应用程序进程意外中止,将不会影响到其它应用程序进程的正常运行。)。Dalvik Virtual Machine在某种角度上很像是JVM(至少我感觉如此),但实际上它们还是有不小的差异的。JVM是堆栈机器(基于Stack),但Dalvik VM是寄存器架构的机器。JVM执行class格式文件,而Dalvik VM执行dex格式文件。 Dalvik VM会通过执行dex码文件来完成堆栈管理、线程管理、安全异常管理、垃圾回收等重要功能,这些也和JVM很像。
Android系统还会通过一些C/C++库来支持我们使用的各个组件(包括OpenGL,SQLite,WebKit等一大堆神奇的引擎和库),这些功能通过应用程序框架提供给开发者,这就是Libraries层。
Application Framework(应用框架)层: 应用框架层的意义在于,Android提供给开发者一个框架开发平台,开发者在遵循框架原则和逻辑的基础上,对框架进行扩展从而开发出各式各样的app应用。开发时也是通过这一层与底层进行交互,并构建更上一级的应用层。这一层包括了各式各样的系统API,同时也可以应用JNI等技术。应用框架包括了Activity Manager,Window Manager,Content Provider,View System等重要组成部分,可以理解为开发者的一个工具箱。
应用层:这一层就是最为形象,和用户直接接触的层次了,包括电话,短信,邮件和各式各样的实用APP、游戏等。
其他特征
- 开发完成后,Android SDK 工具将代码以及所有数据和资源文件一起编译到一个APK: Android 软件包,即 .apk 格式的存档文件中。一个 APK 文件包含 Android 应用的所有内容。
- 默认情况下,每个应用都在自己的 Linux 进程内运行。Android 会在需要执行任何应用组件时启动该进程,然后在不再需要该进程或系统必须为其他应用恢复内存时关闭该进程。
- 默认情况下,每个应用都只能访问执行其工作所需的组件,而不能访问其他组件。 在这样的安全环境中,应用无法访问系统中其未获得权限的部分,但仍然可以通过一些特定的途径与其他应用共享数据以及访问系统服务。
- 应用可以请求访问设备数据(如用户的联系人、短信、可装入存储装置 [SD 卡]、相机、蓝牙等)的权限。所有应用权限都必须由用户在安装时授予。这也就是安装时会列出的“需要的权限”信息。
Android四大组件
Activities
活动一般就是一个单独的用户界面的屏幕。例如,一个电子邮件应用中可能具有一个显示新邮件列表的 Activity、一个用于撰写新邮件的 Activity 以及一个用于阅读邮件具体内容的 Activity。应用中的多个活动通过协作和聚合的方式形成一种有机的整体,完善用户体验,但每个活动都是独立于其他活动而存在的。在这个逻辑上而言,其他某个应用将可以启动电子邮件应用中的某一个活动,比如在相机应用在拍照后启动撰写新邮件的活动。
一个应用通常由多个彼此松散联系的 Activity 组成。 一般会指定应用中的某个 Activity 为“主” Activity,即首次启动应用时呈现给用户的那个 Activity。Activity之间通过Intent组件进行通信。在开发时,每一个Activity都必须要在AndroidManifest.xml配置文件(即清单文件)中声明,否则将无法识别也不执行该Activity。
关于Activity的生命周期:Activity 基本上以三种状态存在,已继续(运行中)、已暂停和已停止。关于活动的七种方法和生命周期详解,可见下图:
Activity的基本方法:
public class ExampleActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // The activity is being created. } @Override protected void onStart() { super.onStart(); // The activity is about to become visible. } @Override protected void onResume() { super.onResume(); // The activity has become visible (it is now "resumed"). } @Override protected void onPause() { super.onPause(); // Another activity is taking focus (this activity is about to be "paused"). } @Override protected void onStop() { super.onStop(); // The activity is no longer visible (it is now "stopped") } @Override protected void onDestroy() { super.onDestroy(); // The activity is about to be destroyed. }}
这些方法共同定义 Activity 的整个生命周期——可以通过实现这些方法监控 Activity 生命周期中的三个嵌套循环:
- Activity 的整个生命周期发生在 onCreate() 调用与 onDestroy() 调用之间。
- Activity 的可见生命周期发生在 onStart() 调用与 onStop() 调用之间。
- Activity 的前台生命周期发生在 onResume() 调用与 onPause() 调用之间。
Services
服务是一种在后台运行的组件,用于执行长时间运行的操作或为远程进程执行作业。服务不提供用户界面。服务不影响其他活动与用户的交互,如用户在浏览器中阅读网页时,另外一个程序的服务可以在后台播放歌曲。活动等其他组件可以启动服务,让其运行或与其绑定以便与其进行交互。
服务有两种,启动和绑定:
- started:当应用组件(如 Activity)通过调用 startService() 启动服务时,服务即处于“启动”状态。一旦启动,服务即可在后台无限期运行,即使启动服务的组件已被销毁也不受影响。可见,当服务是started状态时,其生命周期与启动它的组件无关。
- bound:当应用组件通过调用 bindService() 绑定到服务时,服务即处于“绑定”状态。绑定服务提供了一个客户端-服务器接口, 仅当与另一个应用组件绑定时,绑定服务才会运行。 调用者(如一个Activity)与服务绑定在了一起,调用者一旦退出,服务也就终止。多个组件可以同时绑定到该服务,但全部取消绑定后,该服务即会被销毁。
需要注意的是,服务也可以以两种方式同时存在——问题的关键在于回调方法的具体实现。另外,和Activity一样,在程序清单中需要声明所有服务。
服务的生命周期较为简单:
Content providers
内容提供者管理一组可以共享的应用数据,也叫内容提供程序。其他应用可以通过内容提供程序查询,甚至修改数据(如果内容提供程序允许)。 例如,Android 系统可提供管理用户联系人信息的内容提供程序。另外,内容提供程序也适用于读取和写入不共享的私有数据。它的好处是统一了数据访问方式。Content Provider的主要用法是借助ContentResolver对象用作客户端来与提供程序通信。
内容 URI 是用于在提供程序中标识数据的 URI。内容 URI 包括整个提供程序的符号名称(其权限)和一个指向表的名称(路径)。这里的URI以content://作为前缀,表示该数据由ContentProvider来管理。
Broadcast receivers
广播接收器是一种用于响应系统范围广播通知的组件。 许多广播都是由系统发起的—例如电池电量不足。应用也可以发起广播,如通知其他应用某些数据已下载至设备且可供给使用。应用可以使用它对外部事件进行过滤,只对感兴趣的外部事件通知(如当电话呼入时,或者WIFI网络可用时)进行接收并做出响应。
广播接收器不会显示用户界面,但它们可以创建状态栏通知,在发生广播事件时提醒用户。Broadcast receiver的注册有两种方法,分别是程序动态注册和在AndroidManifest清单文件中进行静态注册。这个组件可以看做是一种程序间通信的“桥梁”。
有关组件的其他
按照官方文档自夸的说法,Android系统设计的独特之处在于,任何应用都可以启动其他应用的组件。例如,如果想让用户使用设备的相机拍摄照片,很可能有另一个应用已经可以执行该操作,那么这个应用就可以利用另外一个应用,而不是开发一个 Activity来自行拍摄照片。
当系统启动某个组件时,会启动该应用的进程(如果尚未运行),并实例化该组件所需的类。四种组件类型中的三种—Activity、服务和广播接收器—通过名为Intent的异步消息进行启动。Intent会在运行时将各个组件相互绑定(可以将 Intent视为请求操作的信使)。
清单文件
在 Android 系统启动应用组件之前,系统必须通过读取应用的AndroidManifest.xml文件(“清单”文件)确认组件存在。应用必须在此文件中声明其所有组件,该文件必须位于应用项目目录的根目录中。AndroidManifest文件中未进行声明的活动、服务以及内容提供者将不为系统所见,从而也就不可用。
当然,清单文件还有别的重要作用,如:
- 确定应用需要的任何用户权限,如互联网访问权限或对用户联系人的读取权限。
- 根据应用使用的 API,声明应用所需的最低API 级别(如6.0系统的API Level就是23,4.3版本则是18)。
- 声明应用使用或需要的硬件和软件功能,如相机、蓝牙服务或多点触摸屏幕。
应用资源
Android应用显然并非只有代码—它还需要与源代码分离的资源,如图像、音频文件以及任何与应用的具体呈现有关的内容。对于每一项资源,SDK 构建工具都会定义一个唯一的整型 ID,利用它可以引用应用代码或 XML 中定义的其他资源中的资源。各种资源理应放入项目 res/ 目录的特定子目录之下,常见的目录有drawable, layout, mipmap, values等。
如何入门Android开发
要入门Android开发,我个人认为需要做好的准备如下:
- 掌握Java语言,至少需要做到写代码不会有语法错误。
- 初步了解Android的世界观,正如上文所述。
- 搭建开发环境,配置好JVM环境(以及JDK等Java环境),Android Studio(谷歌官方推荐的开发平台,已取代Eclipse), Android SDK(用于ADB,应用调试和API管理等)与Genymotion(目前流行的Android Virtual Device插件工具,胜于Android Studio自带的AVD)。
- 学会有效地利用谷歌搜索和安卓官方网站。
以上就是成为一个Android Developer所需的简单准备条件,Android Developing本身是个复杂的体系,学习起来有不小的难度,需要耗费很多时间与精力,但是开发本身无论如何都是一件快乐而充满成就感的事情。
参考资料
这里列出本文的参考资料,同时也为读者提供更多关于本文主题的阅读素材。
https://en.wikipedia.org/wiki/Android_(operating_system)
http://blog.csdn.net/luoshengyang/article/details/8852432
http://blog.csdn.net/andyxm/article/details/6126907/
http://developer.android.com/intl/zh-cn/guide/components/fundamentals.html
http://developer.android.com/intl/zh-cn/ndk/index.html
http://blog.csdn.net/cruise_h/article/details/12610133
http://developer.android.com/guide/index.html
http://blog.csdn.net/ican87/article/details/21874321