Android四大组件
一、概述
Android四大基本组件分别是Activity、Service服务、ContentProvider内容提供者、BroadcastReceiver广播接收器。它们都需要在AndroidManifest.xml配置文件中进行注册。
二、四大组件
2.1 Activity
Activity在屏幕上为用户提供了一个GUI界面,允许用户在上面做一些交互性的操作, 比如打电话、照相、发送邮件。
- 一个Android应用一般有多个Activity。
- Activity之间通过Intent进行通信。
- Andorid应用中每个Activity都必须在AndroidManifest.xml配置文件中进行注册,否则系统将不识别也不执行该Activity。
Activity的相关方法
- onCreate():只在Activity创建时调用,通常做一些初始化设置,不可见。
- onStart():在Activity由不可见变为可见时调用,可见,此时用户可以看到界面,但没有获取到焦点,用户不能进行操作。
- onResume():此时Activity获取到焦点,能够与用户交互,可见。此方法是在与用户进行交互时调用。
- onPause():在当前Activity被其它Activity覆盖或锁屏时调用,可见,但失去焦点。此时会对状态信息和数据进行保存。
- onStop():在Activity不可见时调用,不可见,Activity进入到了后台,且Activity对象仍在内存中。
- **onDestroy()**:在Activity销毁时调用。
- **onRestart()**:当处于Stopped状态的活动需要再次展现给用户时调用。
Activity的生命周期
上述图片中,存在三个周期:
- 整个的生命周期:onCreate() → onStart() → onResume() → Activity running → onPause() → onStop() → onDestory()
- 可见的生命周期:onStart() → onResume() → Activity running → onPause() → onStop() → onRestart()
- 前台的生命周期:onResume() → Activity running → onPause()
Activity栈
Android系统采用栈结构来管理应用程序运行过程中所启动的Activity,即Activity栈。
示例如下:
Activity的四种状态
Active/Running
当前Activity处在屏幕最前端(在Activity栈的顶部),此时可以与用户进行交互,叫做活动状态或运行状态。
Paused
如果当前Activity被一个新的非全屏的Activity 或者一个透明的Activity 覆盖时,此时的状态叫做暂停状态(Paused)。此时它依然保持活力(保持所有的状态,成员信息,和窗口管理器保持连接),所以它仍然可见,但已经失去了焦点故不可与用户进行交互。当内存不足时,Activity通常会被系统杀死。
Stopped
如果当前的Activity被另一个Activity完全遮挡,此时状态叫做停止状态(Stopped)。它仍然保留所有状态和成员信息,但是它不再对用户可见。当内存不足时,Activity通常会被系统杀死。
Killed
Activity被系统终止进程,将该Activity从内存中删除。
Activity的启动模式
Standard标准模式
Activity的默认启动模式。在该模式下,同一个Activity可以被多次实例化。
singleTop 栈顶单例模式
如果需要启动的Activity存在且位于栈顶,则不会重新创建,而是使用栈顶的Activity。但是,如果需要启动的Activity存在但不位于栈顶,那么仍创建新的Activity。
singleTask栈内单例模式
同一个Activity只被允许在系统中有且仅有一个Activity实例。如果系统中已经有了一个实例, 持有这个实例的任务将移动到顶部,同时intent将被通过onNewIntent()发送。 如果没有,则会创建一个新的Activity并置放在合适的任务中。
singleInstance全局单例模式
上面三种模式都是在同一个任务栈中进行的,而这个模式它会另起一个新的任务栈。将一个Activity指定为singleInstance模式,当启动这个Activiy时会使用一个新的任务栈来管理它,与singleTask相同, 同一时刻在系统中只会存在一个这样的Activity实例。
2.2 Service
Service是一种可以长时间运行在后台的,无界面的服务程序。它可以和其他组件进行交互。Service需要在AndroidManifest.xml配置文件中进行注册。
举个例子,比如音乐播放器在后台仍然可以进行音乐的播放、暂停、切歌等操作,这些都是由播放音乐的Service进行控制。
Service的相关方法
- **onCreate()**:Service首次被创建时才会调用该方法。
- **onDestory()**:Service被关闭时会回调该方法。
- **onStartCommand()**:当Service被启动时调用该方法。在此方法中,可以执行如播放媒体文件、下载资源等任务。
- **onbind()**:与目标客户端进行绑定,返回一个 IBinder 对象,app通过该对象与Service组件进行通信。
- **onUnbind()**:只有与Service绑定的所有客户端都取消绑定时,才会调用该方法。
- **stopSelf()**:服务自身调用,用于停止服务。
- **startService()**:客户端请求启动服务,使服务进入“started”状态,即使应用程序已经停止或者已经销毁,服务仍然可以继续运行。
- **stopService()**:客户端请求停止服务,释放所占用的资源。
- **bindService()**:客户端请求绑定服务。
- **unbindService()**:客户端请求解除服务绑定。这个方法用于断开客户端与服务之间的连接。
Service的生命周期
上述图片中,存在两种周期:
StartService
onCreate() → onStartCommand() → Service running → onDestory()
BindService
onCreate() → onBind() → …… → onUnbind() → onDestory()
Service的两种启动方式
- StartService
- 系统对同一个Service只会创建一个Service实例。如果Service实例不存在,调用startService则会实例化一个Service对象,否则复用之前创建的Service实例。
- 通过stopSelf()或StopService()关闭Service。
- 如果调用者直接退出而没有调用StopService,Service会一直在后台运行。该Service的调用者再启动起来后可以通过stopService关闭Service。
- BindService
- 系统对同一个Service只会创建一个Service实例。如果Service实例不存在,调用bindService则会实例化一个Service对象,否则复用之前创建的Service实例。
- 当Service只与一个客户端绑定时,调用unbindService()或者调用者退出,Service会被销毁。当Service与多个客户端绑定时,只有与所有客户端取消绑定后,Service才会被销毁。
2.3 BroadcastReceiver
Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver 是对发送出来的Broadcast进行过滤接受并响应的一类组件。可以使用BroadcastReceiver 来让应用对外部的事件做出响应。
BroadcastReceiver只能执行非常有限的操作,因为它是在主线程中执行的,并且会随着时间的推移而被系统杀死以释放资源。如果BroadcastReceiver需要执行长时间运行的任务,建议使用IntentService或者开启新的线程来执行任务。
BroadcastReceiver的相关方法
**onReceive()**:BroadcastReceiver 必须实现的方法。在接收到广播时,系统会调用该方法。
**setResult()**:设置返回结果和数据。
**getResultCode()**:获取BroadcastReceiver 返回结果的状态码。
**getResultData()**:获取BroadcastReceiver 返回的数据。
**getResultExtras()**:获取BroadcastReceiver 返回的额外数据。
**peekService()**:检查服务是否已启动,返回对应的 IBinder对象。
**setAbortBroadcast()**:终止广播传递,使其他BroadcastReceiver 接收不到该广播。
**getInstance()**:获得广播实例
**registerReceiver()**:注册BroadcastReceiver
**sendBroadcast()**:发送广播
**unregisterReceiver()**:销毁BroadcastReceiver
Broadcast的两种类型
标准广播
完全异步执行的广播,所有的接收者几乎同时接收到广播消息。这种广播不保证接收者能够同时处理广播,也不能保证接收者按照特定的顺序接收到广播。
有序广播
同步执行的一种广播,发出广播后,同一时间只有一个广播接受者能收到,当这个广播接收者的逻辑执行完后,才会传递到下一个接收者。当然,前面的接受者还可以截断广播的继续传递,那么后续接受者就无法收到广播信息了。
BroadcastReceiver的两种注册方法
静态注册
在AndroidManifest,xml配置文件中进行注册。
动态注册
在代码中使用 Context.registerReceiver() 进行注册。
两者区别
- 动态注册的广播接收器与注册它的Activity共存亡。
- 静态注册的广播接收器与设备共存亡。
2.4 ContentProvider
ContentProvider允许应用程序共享数据,并通过URI进行访问。如果一个ContentProvider管理多个数据集,其将会为每个数据集分配一个独立的URI。
Android所提供的ContentProvider都存放在android.provider这个包里面。
ContentProvider需要在AndroidManifest.xml配置文件中进行注册。
ContentProvider的相关方法
ContentProvider 使用 URI 来定义数据集合,并提供了一些标准方法,如查询、插入、更新和删除等,以便其他应用程序可以通过 ContentResolver 访问和操作数据。ContentResolver 可以通过 Context.getContentResolver() 方法获得。
- **onCreate()**:在 ContentProvider 被创建时调用,会及逆行一些初始化工作。
- **query()**:用于获取 ContentProvider 中的数据。
- **insert()**:用于向 ContentProvider 中插入数据。
- **update()**:用于更新 ContentProvider 中现有的数据。
- **delete()**:用于从 ContentProvider中删除数据。
URI
URI(Universal Resource Identifier) 统一资源标识符,每一个 ContentProvider 都对外提供一个能够唯一标识自己数据集的公开URI,这个URI用于表示这个Content Provider提供的数据。
URI被用来标识数据源和操作类型,它通常由以下几部分组成:
- **方案(scheme)**:用于指定访问资源所需要的协议或类型,例如http、https、file、content等。
- **授权(authority)**:分为主机(host)和端口(port)。主机用于标识要访问的主机名或IP地址,对于本地文件,主机可以是localhost或空。端口可选。
- **路径(Path)**:用于标识要访问的资源在服务器中的位置。它由多个单词组成,并通过’/‘分割开来,例如“contacts/people/3”。后面可以增添查询参数(用于传递键值对形式的数据)和片段标识符(Fragment Identifier,用于表示资源中特定部分,例如HTML中的锚点)。
URI通常有以下三种形式:
- scheme**:**//authority/path?query#fragment(用于访问本地资源)
- scheme**://host:**port/path?query#fragment(用于访问网络资源)
- scheme**:**scheme-specific-part#fragment(用于打电话等服务)
一个完整的URI示例如下:
1 |
|
参考: