Android 打卡 Day3 - 四大组件 - 初识
Android 平台架构
Android 是一个适用于移动设备的开源操作系统,由 Google 主导对应的开源项目。整个 Android 以 Linux 的核心作为底层,加上中介函数库和 API,函数库大部分以 C语言设计,框架大多以 Java 相容的程序编写,在这个框架之上才是手机安装的应用。作为一个开源项目,Android 被打造成了一个适用于消费类产品的完整高品质操作系统,并配有可自定义并运用到几乎所有设备的源代码,以及所有用户均可使用的公开文档。
从下往上:
Linux 内核。
HAL - 硬件抽象层。提供标准界面,向更高级别的 Java API 框架显示设备硬件功能。HAL 包含多个库模块,其中每个模块都为特定类型的硬件组件实现一个界面,例如相机或蓝牙模块。当框架 API 要求访问设备硬件时,Android 系统将为该硬件组件加载库模块。
ART - Android Runtime。
原生 C/C++ 库 - 许多核心 Android 系统组件和服务(例如 ART 和 HAL)构建自原生代码,需要以 C 和 C++ 编写的原生库。Android 平台提供 Java 框架 API 以向应用显示其中部分原生库的功能。
Java API 框架- 可通过以 Java 语言编写的 API 使用 Android OS 的整个功能集。这些 API 形成创建 Android 应用所需的构建块,它们可简化核心模块化系统组件和服务的重复使用,包括以下组件和服务:
- 丰富、可扩展的视图系统,可用以构建应用的 UI,包括列表、网格、文本框、按钮甚至可嵌入的网络浏览器
- 资源管理器,用于访问非代码资源,例如本地化的字符串、图形和布局文件
- 通知管理器,可让所有应用在状态栏中显示自定义提醒
- Activity 管理器,用于管理应用的生命周期,提供常见的导航返回栈
- 内容提供程序,可让应用访问其他应用(例如“联系人”应用)中的数据或者共享其自己的数据
开发者可以完全访问 Android 系统应用使用的框架 API。
系统应用(System Apps)- 相机、邮件、短信、日历等。
四大组件
☄️ Activity
一个 Activity 通常就是一个单独的屏幕(窗口)。此窗口通常会填满屏幕,但也可能比屏幕小,并浮动在其他窗口上面。通常,应用中的一个 Activity 会被指定为主 Activity,这是用户启动应用时出现的第一个屏幕。然后,每个 Activity 可以启动另一个 Activity,以执行不同的操作。例如,一个简单的电子邮件应用中的主 Activity 可能会提供显示电子邮件收件箱的屏幕。主 Activity 可能会从该屏幕启动其他 Activity,以提供执行写邮件和打开邮件这类任务的屏幕。
Activity 之间通过 Intent 进行通信。虽然应用中的各个 Activity 协同工作形成统一的用户体验,但每个 Activity 与其他 Activity 之间只存在松散的关联,应用内不同 Activity 之间的依赖关系通常很小。事实上,Activity 经常会启动属于其他应用的 Activity。例如,浏览器应用可能会启动社交媒体应用的“分享”Activity。
Android 应用中每一个 Activity 都必须要在 AndroidManifest.xml 配置文件中声明,并且必须适当地管理 Activity 的生命周期,否则系统将不识别也不执行该 Activity。
使用
<activity>
标签进行声明,唯一的必要属性是android:name
。使用
Intent
显示/隐式请求启动 Activity。生命周期:
onCreate()
在系统创建 Activity 时触发,初始化 Activity 的基本组件、必须在此处调用setContentView()
来定义 Activity 界面的布局。
⬇️onStart()
“已启动”,并对用户可见。此回调包含 Activity 进入前台与用户进行互动之前的最后准备工作。
⬇️onResume()
系统会在 Activity 开始与用户互动之前调用此回调。此时,该 Activity 位于 Activity 堆栈的顶部,并会捕获所有用户输入。应用的大部分核心功能都是在onResume()
方法中实现的。onResume()
回调后面总是跟着onPause()
回调。
⬇️onPause()
当 Activity 失去焦点并进入“已暂停”状态时,系统就会调用onPause()
。例如,当用户点按“返回”或“最近使用的应用”按钮时,就会出现此状态。当系统调用 Activity 的onPause()
时,从技术上来说,这意味着该 Activity 仍然部分可见,但大多数情况下,这表明用户正在离开该 Activity,该 Activity 很快将进入“已停止”或“已恢复”状态。如果用户希望界面继续更新,则处于“已暂停”状态的 Activity 也可以继续更新界面。例如,显示导航地图屏幕或播放媒体播放器的 Activity 就属于此类 Activity。即使此类 Activity 失去了焦点,用户仍希望其界面继续更新。开发者不应使用onPause()
来保存应用或用户数据、进行网络呼叫或执行数据库事务。有关保存数据的信息,请参阅保存和恢复 Activity 状态。onPause()
执行完毕后,下一个回调为onStop()
或onResume()
,具体取决于 Activity 进入“已暂停”状态后发生的情况。
⬇️onStop()
当 Activity 对用户不再可见时,系统会调用onStop()
。出现这种情况的原因可能是 Activity 被销毁、新的 Activity 启动、或者现有的 Activity 正在进入“已恢复”状态并覆盖了已停止的 Activity。在所有这些情况下,停止的 Activity 都将完全不再可见。系统调用的下一个回调将是onRestart()
(如果 Activity 重新与用户互动)或者onDestroy()
(如果 Activity 彻底终止)。⬇️
onRestart()
当处于“已停止”状态的 Activity 即将重启时,系统就会调用此回调。onRestart()
会从 Activity 停止时的状态恢复 Activity。此回调后面总是跟着onStart()
。
⬇️onDestroy()
系统会在销毁 Activity 之前调用此回调。此回调是 Activity 接收的最后一个回调。通常,实现onDestroy()
是为了确保在销毁 Activity 或包含该 Activity 的进程时释放该 Activity 的所有资源。
生命周期整体上和 iOS 类似。
☄️ Service
Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。Service 可由其他应用组件启动,而且即使用户切换到其他应用,Service 仍将在后台继续运行。此外,组件可通过绑定到 Service 与之进行交互,甚至是执行进程间通信 (IPC)。Service 组件通常用于为其他组件提供后台服务或监控其他组件的运行状态,例如,服务可在后台处理网络事务、播放音乐,执行文件 I/O 或与内容提供程序进行交互。
Service 的启动方式分为两种:
- Started(启动):当应用程序组件(如 activity)调用
startService()
方法启动服务时,服务处于 started 状态。 - Bound(绑定):当应用程序组件调用
bindService()
方法绑定到服务时,服务处于 bound 状态。
- Started(启动):当应用程序组件(如 activity)调用
startService() 与 bindService() 区别:
- Started Service(启动服务)是由其他组件调用
startService()
方法启动的,这导致服务的onStartCommand()
方法被调用。当服务是 started 状态时,其生命周期与启动它的组件无关,并且可以在后台无限期运行,即使启动服务的组件已经被销毁。因此,服务需要在完成任务后调用stopSelf()
方法停止,或者由其他组件调用stopService()
方法停止。 - Bound Service(绑定服务)使用
bindService()
方法启用服务,调用者与服务绑定在了一起,调用者一旦退出,服务也就终止,“不求同年同月同日生,必须同年同月同日死”。
- Started Service(启动服务)是由其他组件调用
如同 Activity 及其他组件的操作一样,开发者必须在 AndroidManifest.xml 文件中声明所有服务,使用
标签。 生命周期:
左图显示使用
startService()
创建的服务的生命周期,右图显示使用bindService()
创建的服务的生命周期,两者还可以嵌套循环使用。
☄️ Content Provider
- Content Provider 使一个应用程序的指定数据集提供给其他应用程序,是一种标准接口。其他应用可以通过 ContentResolver 类从该内容提供者中访问或修改数据。
- 只有需要在多个应用程序间共享数据是才需要内容提供者。例如,通讯录数据被多个应用程序使用,且必须存储在一个内容提供者中。它的好处是统一数据访问方式。
- ContentProvider 实现数据共享。ContentProvider 用于保存和获取数据,并使其对所有应用程序可见。这是不同应用程序间共享数据的唯一方式,因为 Android 没有提供所有应用共同访问的公共存储区。
- 开发人员不会直接使用 ContentProvider 类的对象,大多数是通过 ContentResolver 对象实现对 ContentProvider 的操作。
- ContentProvider 使用 URI 来唯一标识其数据集,这里的 URI 以 content:// 作为 scheme,表示该数据由 ContentProvider 来管理。
☄️ Broadcast Receiver
- 类似发布-订阅的设计模式,应用可以订阅特定的广播,对外部事件进行过滤,只对感兴趣的外部事件 (如当电话呼入时,或者数据网络可用时) 进行接收并做出响应。广播接收器没有用户界面。然而,它们可以启动一个 Activity 或 Service 来响应它们收到的信息,或者用 NotificationManager 来通知用户,通知可以用很多种方式来吸引用户的注意力,例如闪动背灯、震动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。
- 应用可以通过两种方式接收广播:清单声明的(静态)接收器和上下文注册的(动态)接收器。
- 动态注册广播接收器特点是当用来注册的 Activity 关掉后,广播也就失效了。静态注册无需担忧广播接收器是否被关闭,只要设备是开启状态,广播接收器也是打开着的。也就是说即使 App 本身未启动,该 app 订阅的广播在触发时也会对它起作用。
🔆 概念理解起来还算顺利,Activity 类似 ViewController,Content Provider 一定程度上类似文件分享?,Broadcast 类似 iOS 的远程/本地通知,还有 Service 和 iOS 的小组件有点类似,但是限制明显比 iOS 少一些…
Demo
仅用于记录学习过程,不具备指导性。🤓
下一日目标:Demo 中实践四大组件。