写在前面的话
假设对Android开发还不是特别了解的同学。能够參考我之前翻译的Android开发教程。
http://blog.csdn.net/column/details/development4android.html
软件栈
- 应用层。包含使用Java库和Android框架所编写的程序。
- Core Java
- Java类库,并非全然的Java SE或Java ME的实现。而是Apache Harmony的一个实现。基于Java5。这一层提供基础的Java线程机制。包含java.lang.Thread类和java.util.concurrent包。
- Application framework
- Android框架层,主要负责处理窗体系统。UI组件,资源等。基本上,要编写一个Android应用所须要的全部类都在这一层。
同一时候,Android框架定义和管理Android组件的生命周期和它们之间的通信。
而且,Android框架定义了一系列Android特有的异步机制,包含HandlerThread。AsyncTask,IntentService,AsyncQueryHandler和Loaders。
- Native libraries
- C/C++库层,主要负责处理图像。音视频。数据库,字体,OpenGL等。Java所编写的程序并不直接和这一层交流,由于Android框架已经对这些本地代码进行了封装。
- Runtime
- 运行时环境。即Dalvik虚拟机。为每个Android应用程序提供了一个沙盒,Dalvik虚拟机运行.dex文件。每个程序都运行在它专有的Dalvik虚拟机中。
- Linux kernel
- Linux内核,即潜在的操作系统。
负责让程序使用硬件功能,比如声音,网络。相机等。
同一时候,负责管理进程和线程。
为每个程序开启一个进程。每个进程掌管一个Dalvik虚拟机。
在进程中。多线程运行程序的代码。
Linux内核通过调度机制。为进程和它们的线程分配可用的CPU运行时间。
Applications
程序架构
一个程序的基础是Application对象以及Android的组件:Activity,Service。BroadcastReceiver和ContentProvider。
程序 Application
一个程序在Java中的表达方式就是android.app.Application对象。
当程序开启的时候,这个对象被创建,程序停止时被销毁。也就是说,Application对象经历一个Linux进程的完整生命周期。
当Linux进程又一次开启的时候,一个新的Application对象也被创建了。
组件
Android的组件包含Activity,BroadcastReceiver。Service和ContentProvider。
这些实体有不同的责任和生命周期,但它们都代表了程序的入口,也就是程序启动的地方。
Intent
一个组件唤醒还有一个组件是通过Intent才干实现的,这个过程能够发生在同一个程序中或多个程序之间。
Intent分为显式的和隐式的:
- 显式的 Intent
- 定义一个组件的完整的名字,这个名字在运行时能够能够被程序识别。
- 隐式的 Intent
- 通过IntentFilter在运行时与组件绑定,须要在IntentFilter中定义一些“协议”。
假设Intent与IntentFilter中的“协议”匹配,那么这个组件就会被启动。
组件的生命周期是Android系统特定的技术,它们不与潜在的Java对象匹配。一个Java对象能够比它的组件存活的时间要久,而且。Dalvik虚拟机能够保存与一个组件的相应的多个对象。小心,这会导致内存泄漏。我会在后面对多线程造成的内存泄漏进行分析。
通常。实现一个组件的方式是子类化它。
而且。一个程序中全部的组件都要在AndroidManifest.xml中进行注冊。
Activity
一个Activity就是一个屏幕。通常占领了设备的全部屏幕尺寸。它用来展示信息,处理用户的输入等。
包含全部的UI组件,比如button。文本框,图片等。
Activity持有一个对全部视图树的对象引用。所以它占领的内存会变的非常大。
当用户在不同的屏幕之间导航的时候,Activity实例从一个栈里面被初始化。当导航到一个新的屏幕时,一个新的Activity被压入到栈里,当返回到之前的屏幕时,Activity被从栈中弹出。
在以下的图中,首先开启了一个Activity A,接着切换到B。同一时候A销毁;然后切换到C和D。A,B,C是全屏显示的,可是D是窗体模式的,只占领了屏幕的一部分空间。A全然被销毁了,B是不可见的。C是部分可见的,D是全部可见的,而且D在栈顶。因此,D获得了焦点而且能够接收用户的输入。
Activity在栈里面的位置,决定了Activity的状态:
- 可见而且处于活跃状态: D
- 暂停而且部分可见: C
- 停止而且全然不可见: B
- 不可交互而且已经全然销毁: A
一个程序中最顶端的Activity。对这个程序在系统中的优先级是有一定影响的。这里所谓的优先级就是进程的优先级,这将影响一个程序被终止的几率和分配给这个程序中线程的运行时间。
按返回键或者调用finish()方法都会终止一个Activity的生命周期。
Service
Service是在后台运行的。它是不可见的。和用户之间也没有不论什么交互的。能够用来从其它组件卸载一些操作,这些操作比那些组件活的要长。一个Service能够用过两种方式去运行,start或bind:
- Started Service
- 通过调用Context.startService(Intent)开启服务,这里的Intent既能够是隐式的,也能够是显式的。假设想要停止服务。调用 Context.stopService(Intent)。
- Bound Service
- 通过调用Context.bindService(Intent, ServiceConnection, int),多个组件能够绑定同一个Service。这里的Intent既能够是隐式的。也能够是显式的。绑定之后。通过ServiceConnection接口与Service进行通信。假设想要停止服务,调用 Context.unbindService(ServiceConnection)。当最后一个组件与Service解绑后,这个Service就会被销毁。
ContentProvider
一个程序想要共享大量的数据。无论是在这个程序中。还是多个程序之间,都能够使用ContentProvider。
它提供了获取数据的入口。通常适合SQLite数据库一起使用。SQLite数据库是对程序私有的,可是通过ContentProvider就能够实现进程之间的数据共享了。
BroadcastReceiver
它监听从一个程序之中。程序之间,或系统发出的Intent。总而言之,就是它监听手机中全部的Intent。然后过滤这些收到的Intent。确定哪一个须要被处理。
一个BroadcastReceiver应该动态注冊,也就是说注冊在须要使用它的地方。这样能够对它进行控制。
假设静态注冊在了AndroidManifest.xml中,那么当这个程序在安装的时候,它就一直在监听Intent,无论这些Intent对它是不是实用。
如此一来。假设某一个Intent匹配了某一个IntentFilter,那么这个BroadcastReceiver就会开启与之关联的程序。
这里具体说一下,假设有一个程序A。在AndroidManifest.xml中注冊了一个监听网络变化的BroadcastReceiver。
此时,A没有被打开,也就是说此时系统中并没有A的进程。
当系统的网络发生变化时,由于这个BroadcastReceiver的存在,A的进程被创建了。A相应的Application对象也就随之被创建了!
由于BroadcastReceiver被认定是进入一个app的入口。这样的入口还包含Activity。Service和ContentProvider。
參考资料
http://developer.android.com/guide/components/index.html
版权声明:本文博客原创文章。博客,未经同意,不得转载。