Android四大组件
Android有四大基本组件:
- Activity
- Service
- BroadcastReceiver
- Content Provider。
Activity
1、Activity介绍
Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务
Activity中所有操作都与用户密切相关,是一个负责与用户交互的组件,可以通过setContentView(View)来显示指定控件
在一个android应用中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。Activity之间通过Intent进行通信
2、Activity四种基本状态
(1)Active/Running
一个新 Activity 启动入栈后,它显示在屏幕最前端,处于栈的最顶端(Activity栈顶),此时它处于可见并可和用户交互的激活状态,叫做活动状态或者运行状态
(2)Paused
当 Activity失去焦点, 被一个新的非全屏的Activity 或者一个透明的Activity 被放置在栈顶,此时的状态叫做暂停状态(Paused)。此时它依然与窗口管理器保持连接,Activity依然保持活力(保持所有的状态,成员信息,和窗口管理器保持连接),但是在系统内存极端低下的时候将被强行终止掉。所以它仍然可见,但已经失去了焦点故不可与用户进行交互。
(3)Stopped
如果一个Activity被另外的Activity完全覆盖掉,叫做停止状态(Stopped)。它依然保持所有状态和成员信息,但是它不再可见,所以它的窗口被隐藏,当系统内存需要被用在其他地方的时候,Stopped的Activity将被强行终止掉。
(4)Killed
如果一个Activity是Paused或者Stopped状态,系统可以将该Activity从内存中删除,Android系统采用两种方式进行删除,要么要求该Activity结束,要么直接终止它的进程。当该Activity再次显示给用户时,它必须重新开始和重置前面的状态。
3、Activity状态转换
当一个 Activity 实例被创建、销毁或者启动另外一个 Activity 时,它在这四种状态之间进行转换,这种转换的发生依赖于用户程序的动作
如上图所示,Android程序员可以决定一个 Activity 的“生”,但不能决定它的“死”,也就是说程序员可以启动一个 Activity,但是却不能手动的“结束”一个 Activity
当你调用Activty.finish()方法时,结果和用户按下 BACK 键一样:告诉 Activity Manager 该 Activity 实例完成了相应的工作,可以被“回收”。随后 Activity Manager 激活处于栈第二层的 Activity 并重新入栈,同时原 Activity 被压入到栈的第二层,从 Active 状态转到 Paused 状态
例如:从 Activity1 中启动了 Activity2,则当前处于栈顶端的是 Activity2,第二层是 Activity1,当我们调用Activity2.finish()方法时,Activity Manager 重新激活 Activity1 并入栈,Activity2 从 Active状态转换Stoped 状态,Activity1.onActivityResult(int requestCode, int resultCode, Intent data)方法被执行,Activity2 返回的数据通过data参数返回给 Activity1
4、Activity栈
Android 是通过一种 Activity 栈的方式来管理 Activity 的,一个 Activity 的实例的状态决定它在栈中的位置。处于前台的 Activity 总是在栈的顶端,当前台的 Activity 因为异常或其它原因被销毁时,处于栈第二层的 Activity 将被激活,上浮到栈顶。当新的 Activity 启动入栈时,原 Activity 会被压入到栈的第二层。一个 Activity 在栈中的位置变化反映了它在不同状态间的转换。Activity 的状态与它在栈中的位置关系如下图所示
Activity 的状态与它在栈中的位置关系
如上图所示,除了最顶层即处在 Active 状态的 Activity 外,其它的 Activity 都有可能在系统内存不足时被回收,一个 Activity 的实例越是处在栈的底层,它被系统回收的可能性越大。系统负责管理栈中 Activity 的实例,它根据 Activity 所处的状态来改变其在栈中的位置
5、方法通知
下面的图显示了Activity的重要状态转换,矩形框表明Activity在状态转换之间的回调接口,开发人员可以重载实现以便执行相关代码,带有颜色的椭圆形表明Activity所处的状态。
在上图中,Activity有三个关键的循环:
- 整个的生命周期,从onCreate(Bundle)开始到onDestroy()结束。Activity在onCreate()中设置所有的“全局”状态,在onDestory()中释放所有的资源
例如:某个Activity有一个在后台运行的线程,用于从网络下载数据,则该Activity可以在onCreate()中创建线程,在onDestory()中停止线程
- 可见的生命周期,从onStart()开始到onStop()结束。在这段时间,可以看到Activity在屏幕上,尽管有可能不在前台,不能和用户交互。在这两个接口之间,需要保持显示给用户的UI数据和资源等
例如:可以在onStart()中注册一个IntentReceiver来监听数据变化导致UI的变动,当不再需要显示时候,可以在onStop()中注销它。onStart(),onStop()都可以被多次调用,因为Activity随时可以在可见和隐藏之间转换。
- 前台的生命周期,从onResume()开始到onPause()结束。在这段时间里,该Activity处于所有 Activity的最前面,和用户进行交互。Activity可以经常性地在resumed和paused状态之间切换
例如:当设备准备休眠时、当一个 Activity处理结果被分发时、当一个新的Intent被分发时。所以在这些接口方法中的代码应该属于非常轻量级的
6、Activity生命周期
(1)onCreate():在Activity创建时调用,通常做一些初始化设置,不可见,只在Activity创建时执行一次
(2)onStart():在Activity即将可见时调用,可见,在Activity中多次调用,不在前台,不可交互,初始化工作
(3)onResume():在Activity获取焦点开始与用户交互时调用,在前台,开启动画和独占设备
(4)onPause():在当前Activity被其它Activity覆盖或锁屏时调用,可见,程序状态的保存,独占设备和动画的关闭,以及一些数据的保存最好在onPause中进行,但不能太耗时
(5)onStop():在Activity对用户不可见时调用,不可见,其对象还在内存中,系统内存不足时可能不会执行onStop()方法
(6)onDestroy():在Activity销毁时调用
(7)onRestart():在Activity从停止状态再次启动时调用
Service
1、Service介绍
Service是android系统的四大组件之一,是一种长生命周期的,没有可视化界面,运行于后台的一种服务程序
2、启动方式
(1)Started Service
被开启的service通过其他组件调用startService()被创建,这种service可以无限地运行下去,必须调用stopSelf()方法或者其他组件调用stopService()方法来停止它,当service被停止时,系统会销毁它
(2)Bounded Service
被绑定的service是当其他组件(一个客户)调用bindService()来创建的,客户可以通过一个IBinder接口和service进行通信,客户可以通过unbindService()方法来关闭这种连接,一个service可以同时和多个客户绑定,当多个客户都解除绑定之后,系统会销毁service
3、Service生命周期
(1)service整体的生命时间是从onCreate()被调用开始,到onDestroy()方法返回为止。和activity一样,service在onCreate()中进行它的初始化工作,在onDestroy()中释放残留的资源
比如,一个音乐播放service可以在onCreate()中创建播放音乐的线程,在onDestory()中停止这个线程
onCreate()和onDestroy()会被所有的service调用,不论service是通过startService()还是bindService()建立
(2)service积极活动的生命时间(active lifetime)是从onStartCommand()或onBind()被调用开始,它们各自处理由startService()或bindService()方法传过来的Intent对象
如果service是被开启的,那么它的活动生命周期和整个生命周期一同结束。
如果service是被绑定的,那么它的活动生命周期是在onUnbind()方法返回后结束。
BroadcastReceiver
1、BroadcastReceiver介绍
BroadcastReceiver(广播接收器)是Android系统的四大组件之一,用于监听 / 接收 应用发出的广播消息,并做出响应
应用场景:不同组件之间通信(包括应用内 / 不同应用之间);与 Android 系统在特定情况下的通信(如当电话呼入时、网络可用时);多线程通信
Android 广播分为两个角色:广播发送者、广播接收者
2、实现原理
Android中的广播使用了设计模式中的观察者模式:基于消息的发布/订阅事件模型
模型中有3个角色:
- 消息订阅者(广播接收者)
- 消息发布者(广播发布者)
- 消息中心(AMS,即Activity Manager Service)
广播接收者通过 Binder机制在AMS注册
广播发送者通过 Binder 机制向AMS发送广播
AMS根据广播发送者要求,在已注册列表中,寻找合适的广播接收者(寻找依据:IntentFilter / Permission)
AMS将广播发送到合适的广播接收者相应的消息循环队列中
广播接收者通过消息循环拿到此广播,并回调 onReceive()
Content Provider
1、Content Provider介绍
Content Provider属于Android应用程序的组件之一,作为应用程序之间唯一的共享数据的途径,Content Provider为存储和读取数据提供了统一的接口。Content Provider主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口
Android系统为一些常见的数据类型(如音乐、视频、图像、手机通信录联系人信息等)内置了一系列的Content Provider,这些都位于android.provider包下。持有特定的许可,可以在自己开发的应用程序中访问这些Content Provider
使用Content Provider,应用程序可以实现数据共享
让自己的数据和其他应用程序共享有两种方式:
- 创建自己的Content Provider(即继承ContentProvider的子类)
- 将自己的数据添加到已有的Content Provider中去
后者需要保证现有的Content Provider和自己的数据类型相同且具有该Content Provider的写入权限
2、数据模型
Content Provider将其存储的数据以数据表的形式提供给访问者,在数据表中,每一行为一条记录,每一列为具有特定类型和意义的数据。每一条数据记录都包括一个"ID"数值字段,该字段唯一标识一条数据
3、URI
URI(Universal Resource Identifier)统一资源标识符,每一个Content Provider都对外提供一个能够唯一标识自己数据集的公开URI,这个Uri用于表示这个Content Provider提供的数据
Android所提供的Content Provider都存放在android.provider这个包里面
如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。所有的Content Provider的URI都以”content://”开头,其中”content:”是用来标识数据是由Content Provider管理的schema
自定义URI的格式如下:
[scheme:][//Authority][path][?query]
例:content://com.sousuo.people/user/1
- scheme:主题,Content Provider的URI前缀 content://
- Authority:授权信息,Content Provider的唯一标识符 com.sousuo.people(包名.类名)
- path:表名,Content Provider指向数据库中的某个表名 user
- query:查询表中的某个记录(若无指定,则返回全部记录) 1
4、数据查询
URI有两种形式
- 一种现实某些数据类型的所有的值(比如,所有的个人联系信息)
- 还有一种显示某种数据类型的一个特定的记录
content://contacts/people/是第一种形式的URI,它会返回设备上所有的联系人的名字
content://contacts/people/23是第二种形式的URI,只返回ID=23的那行
content://media/images 返回设备上所有图片的列表
Android在android.provider包中提供了一系列的辅助类,它们定义了这些查询字符串,所以不必知道不同数据类型真正的URI值。这些辅助类定义了一个叫CONTENT_URI的字符串
比如android.provider.contacts.People.CONTENT_URI定义了用于在android自带的people content provider中查找联系人的查询字符串