[Android]四大组件简介

在 Android 开发中,“四大组件”(Four Major Components)是指构成 Android 应用程序的四种核心组件,它们通过各自的方式与系统交互,实现应用的多样功能。这些组件是:Activity、Service、Broadcast Receiver 和 Content Provider。每个组件都扮演着不同的角色,并且通过各自的生命周期、方法和目的与 Android 操作系统交互。

一、Activity

在 Android 应用中,Activity 是一个非常核心的组件,用于表示应用的一个单一屏幕,是用户与应用交互的主界面。每个 Activity 提供一个窗口,用于绘制界面和接收与用户的交互事件。理解 Activity 的创建、生命周期和其基本用法对于开发 Android 应用至关重要。

基本概念

一个 Android 应用通常由多个 Activity 组成,每个 Activity 都是一个独立的界面。当你打开一个应用,如邮箱应用,你看到的邮箱列表、邮件详情、写邮件等各个界面,通常都是不同的 Activity

生命周期

Activity 的生命周期是其最重要的特征之一。Android 提供了一系列的回调方法来管理 Activity 的状态,包括用户开始使用 ActivityActivity 进入前台或后台,以及 Activity 被系统销毁的时刻。

下面是 Activity 生命周期的主要方法:

  • onCreate(Bundle savedInstanceState): 当 Activity 被创建时调用。这是初始化界面、成员变量等的地方。
  • onStart(): 当 Activity 对用户可见时调用。
  • onResume(): 当 Activity 准备好与用户交互时调用,此时 Activity 位于前台。
  • onPause(): 当系统即将启动或恢复另一个 Activity 时调用。用于保存数据或释放资源。
  • onStop(): 当 Activity 不再对用户可见时调用。
  • onDestroy(): 当 Activity 即将被销毁时调用。

示例代码

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivityclass MainActivity : AppCompatActivity() {// 当 Activity 被创建时调用override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 设置 Activity 的布局文件setContentView(R.layout.activity_main)// 进行初始化操作,比如从 Bundle 恢复数据if (savedInstanceState != null) {val savedValue = savedInstanceState.getString("key")// 使用恢复的数据}}// 当 Activity 开始对用户可见时调用override fun onStart() {super.onStart()}// 当 Activity 准备好与用户交互时调用override fun onResume() {super.onResume()}// 当 Activity 即将停止与用户交互时调用override fun onPause() {super.onPause()// 保存数据或释放资源}// 当 Activity 不再完全可见时调用override fun onStop() {super.onStop()}// 当 Activity 即将被销毁时调用override fun onDestroy() {super.onDestroy()}// 保存 Activity 状态override fun onSaveInstanceState(outState: Bundle) {super.onSaveInstanceState(outState)outState.putString("key", "value")}
}

注意事项

  1. 管理资源:由于 Android 设备的资源有限,合理管理 Activity 的资源非常重要。例如,在 onPause() 或 onStop() 中释放那些不需要的资源。
  2. 状态保存与恢复:Android 系统可能因为资源不足等原因随时终止 Activity。因此,在 onSaveInstanceState(Bundle outState) 中保存重要状态,并在 onCreate(Bundle savedInstanceState) 中恢复状态是很重要的。
  3. 用户界面响应:保证 Activity 响应用户的操作,避免在主线程(UI线程)进行耗时操作,这样可以防止应用界面冻结。

二、Service

在 Android 开发中,Service 是一种用于在后台执行长时间运行的任务而不提供用户界面的应用组件。Service 可以在应用的前台或者后台执行任务,即使用户离开了应用。服务是用来处理不需要与用户交互而需要长期运行的操作,例如在后台播放音乐、执行文件下载等。

基本类型

Service 主要有两种形式:

  1. 前台服务(Foreground Service):前台服务显示一个持续的通知,这意味着用户清楚地知道正在运行的服务。这种服务用于用户积极参与的任务(如播放音乐)或对用户很重要的任务(如文件下载)。
  2. 后台服务(Background Service):在应用不在屏幕上显示时执行的服务。从 Android Oreo(8.0)开始,后台服务的运行受到了严格限制以优化应用对设备电池生命的影响。

生命周期方法

Service 有自己的生命周期方法,用于管理其创建、启动、绑定和销毁过程:

  • onCreate(): 服务创建时调用。
  • onStartCommand(Intent intent, int flags, int startId): 每次通过 startService() 方法启动服务时调用。
  • onBind(Intent intent): 当其他组件想要与服务绑定时调用,需要返回一个 IBinder 对象,通过该对象组件可以与服务进行通信。
  • onUnbind(Intent intent): 当所有组件都与服务解除绑定时调用。
  • onDestroy(): 服务销毁之前调用。

示例代码

下面是一个简单的服务示例,该服务在后台记录日志。

import android.app.Service
import android.content.Intent
import android.os.IBinder
import android.util.Logclass MyService : Service() {// 当服务被创建时调用override fun onCreate() {super.onCreate()Log.d("MyService", "服务已创建")}// 每次服务启动时调用override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {Log.d("MyService", "服务正在运行")// 如果我们希望服务在终止后重启,则返回 START_STICKYreturn START_STICKY}// 当服务被销毁时调用override fun onDestroy() {super.onDestroy()Log.d("MyService", "服务已销毁")}// 当其他组件想要绑定服务时调用override fun onBind(intent: Intent): IBinder? {// 本示例不提供绑定功能,因此返回 nullreturn null}
}

在 AndroidManifest.xml 中注册服务

要使服务能够运行,必须在应用的 AndroidManifest.xml 文件中进行声明:

<application...><service android:name=".MyService" />
</application>

启动和停止服务

你可以从 Activity 或其他组件中启动和停止服务。

val intent = Intent(this, MyService::class.java)
startService(intent)  // 启动服务
stopService(intent)   // 停止服务

注意事项

  • 资源管理:服务可以无限运行,但这可能消耗大量的电池和计算资源。确保服务不会无谓地消耗资源。
  • 服务和线程:服务运行在应用的主线程中,因此如果在服务中执行耗时操作,需要手动创建新线程来处理这些操作,以避免阻塞主线程。
  • 服务的适用场景:在考虑使用服务之前,评估是否真的需要服务。对于简单的、短暂的后台操作,可以考虑使用 WorkManager 或 AlarmManager

三、Broadcast Receiver

在 Android 中,Broadcast Receiver(简称广播接收器)是一个用来处理来自系统或应用发出的广播通知的组件。它可以对诸如设备启动完成、电池电量变化、短信接收等系统事件做出响应,也可以接收应用自定义的广播消息。

基本概念

广播接收器主要用于监听和响应广播消息。广播可以是系统广播(比如网络状态改变、屏幕关闭等),也可以是应用程序发送的广播。广播接收器本身没有用户界面,但它可以启动一个活动或服务来响应接收到的信息。

生命周期和类型

广播接收器不像 Activity 或 Service 那样拥有完整的生命周期。它只有一个回调方法 onReceive(Context context, Intent intent),当接收到广播时被调用。广播接收器的类型分为两种:

  • 静态注册:在 AndroidManifest.xml 中注册。即使应用没有运行,只要事件发生,系统就会创建广播接收器的实例并调用它。
  • 动态注册:在代码中注册,通常在 Activity 或 Service 中注册。它只在其宿主组件(如 Activity)存在时活跃。

示例代码

下面是一个静态注册的广播接收器,用于接收设备启动完成后的广播:

AndroidManifest.xml:

<application ... ><receiver android:name=".BootCompletedReceiver"><intent-filter><action android:name="android.intent.action.BOOT_COMPLETED" /></intent-filter></receiver>
</application>

BootCompletedReceiver.kt:

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.widget.Toastclass BootCompletedReceiver : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent) {// 确认接收到的是设备启动完成的广播if (intent.action == Intent.ACTION_BOOT_COMPLETED) {Toast.makeText(context, "设备启动完成!", Toast.LENGTH_LONG).show()// 可以在这里启动一个服务或进行其他操作}}
}

下面是动态注册的广播接收器示例,用于在 Activity 中监听网络变化:

MainActivity.kt:

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivityclass MainActivity : AppCompatActivity() {private lateinit var networkChangeReceiver: BroadcastReceiveroverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 初始化广播接收器networkChangeReceiver = object : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent) {// 检查网络状态变化Toast.makeText(context, "网络状态变化", Toast.LENGTH_SHORT).show()}}// 注册接收器监听网络变化IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).also {registerReceiver(networkChangeReceiver, it)}}override fun onDestroy() {super.onDestroy()// 动态注册的接收器必须要取消注册unregisterReceiver(networkChangeReceiver)}
}

注意事项

  • 性能和资源管理:广播接收器的 onReceive() 方法应该尽快完成,不要进行任何耗时操作,以免阻塞主线程。若需要执行较长时间的任务,应该启动一个 Service
  • 权限问题:接收某些系统广播可能需要声明相应的权限,比如接收开机广播需要声明 RECEIVE_BOOT_COMPLETED 权限。
  • 条件广播和有序广播:Android 提供了条件广播和有序广播两种方式。有序广播允许多个接收器按顺序接收到同一个广播,每个接收器可以终止广播,防止它传递给其他接收器。

四、Content Provider

在 Android 中,Content Provider 是四大组件之一,用于在不同应用程序之间共享数据。它提供了一种封装数据的方式,并通过一套标准的 API 在应用之间进行数据访问。通过使用 Content Provider,一个应用可以允许其他应用访问其数据,而不需要直接访问底层数据库或文件系统。

基本概念

Content Provider 管理对一个或多个数据源(如 SQLite 数据库)的访问,通过 URI(统一资源标识符)来暴露数据。每个 URI 可以指代 Content Provider 中的数据表或表内的特定数据行。通过这种方式,Content Provider 为数据访问提供了封装,并确保了数据访问的安全性。

核心组件

  • URI: 每个 Content Provider 都通过一个唯一的 authority 来标识,该 authority 与 URI 结合使用,用来找到对应的 Content Provider
  • ContentResolver: 提供了一组 API,允许应用查询或修改由 Content Provider 管理的数据。应用通过调用 ContentResolver 的方法,如 query()insert()delete(), 和 update() 来执行操作。

创建一个 Content Provider

创建一个 Content Provider 通常包括以下几个步骤:

  1. 扩展 ContentProvider 类:
    实现必要的方法:onCreate()query()insert()delete(), 和 update()

  2. 在 AndroidManifest.xml 中声明:
    注册 Content Provider 并定义一个唯一的 authority

  3. 使用 URI 访问数据:
    定义和解析 URI 来访问 Content Provider 管理的数据。

示例代码

下面是一个简单的 Content Provider 实现示例:

MyContentProvider.kt:

import android.content.ContentProvider
import android.content.ContentValues
import android.database.Cursor
import android.net.Uriclass MyContentProvider : ContentProvider() {// 初始化内容提供者override fun onCreate(): Boolean {// 初始化数据源等return true}// 查询数据override fun query(uri: Uri,projection: Array<String>?,selection: String?,selectionArgs: Array<String>?,sortOrder: String?): Cursor? {// 根据 uri 查询数据return null // 示例中返回 null,实际使用时返回查询结果的 Cursor}// 插入数据override fun insert(uri: Uri, values: ContentValues?): Uri? {// 插入数据到数据源return null // 示例中返回 null,实际使用时返回新插入数据的 Uri}// 删除数据override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {// 根据 uri 和条件删除数据return 0 // 示例中返回 0,实际使用时返回被删除的行数}// 更新数据override fun update(uri: Uri,values: ContentValues?,selection: String?,selectionArgs: Array<String>?): Int {// 根据 uri 更新数据return 0 // 示例中返回 0,实际使用时返回被更新的行数}// 返回 MIME 类型override fun getType(uri: Uri): String? {// 根据 uri 返回 MIME 类型return null}
}

AndroidManifest.xml:

<application ... ><providerandroid:name=".MyContentProvider"android:authorities="com.example.myapp.provider"android:exported="true"/>
</application>
使用 Content Provider

其他应用可以通过 ContentResolver 访问 Content Provider

val contentResolver = getContentResolver()
val uri = Uri.parse("content://com.example.myapp.provider/table_name")
val cursor = contentResolver.query(uri, null, null, null, null)

注意事项

  • 权限管理:确保在 AndroidManifest.xml 中配置合适的权限,以保护数据不被未授权访问。可以通过 android:exported 和 android:permission 控制对 Content Provider 的访问。
  • 线程安全Content Provider 的方法可能会被多个线程同时调用,因此实现时需要考虑线程安全。
  • 性能优化:由于 Content Provider 可能会频繁地进行数据库操作,合理设计和优化数据库访问逻辑非常重要,以避免性能瓶颈。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/7356.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

6个月小猫成长必备!福派斯无麸质幼猫粮评测

你知道吗&#xff1f;给小猫选择适合的猫粮是一件非常不容易但很重要的事情。那么&#xff0c;对于6个月大的小猫来说&#xff0c;什么样的猫粮是最适合它们的呢&#xff1f;&#x1f431; 我们首先要考虑的是猫粮的营养成分。6个月大的小猫正处于快速生长期&#xff0c;所以需…

远程连接是什么?

远程连接是指通过网络连接两个或多个设备&#xff0c;实现远程访问、控制或传输数据的技术。它在现代科技发展中起到了重要作用&#xff0c;使得我们可以随时随地与远程设备进行交互、管理和操作。 天联组网是一种高效的远程连接解决方案&#xff0c;它因为操作简单、跨平台应用…

git使用注意事项事项

以下操作均在gitee平台上实现 文章目录 1、本地仓库和远程仓库有冲突2、git提交自动忽略某些文件3、git无法push提交到远程仓库 1、本地仓库和远程仓库有冲突 在web端修改了文件内容或者删除了文件&#xff0c;本地仓库需要重新把远程仓库拉取到本地&#xff0c;或者强制提交到…

Prometheus 2: 一个专门评估其他语言模型的开源语言模型(续集)

普罗米修斯的续集来了。 专有的语言模型如 GPT-4 经常被用来评估来自各种语言模型的回应品质。然而,透明度、可控制性和可负担性等考虑强烈促使开发专门用于评估的开源语言模型。另一方面,现有的开源评估语言模型表现出关键的缺点:1) 它们给出的分数与人类给出的分数存在显著差…

图像处理-图像平滑

图像平滑 前言一、概念介绍1.1 图像的平滑1.2 图像中噪声的分类1.3 MATLAB的添加噪音代码 二、空间域平滑滤波2.1 均值滤波2.2 原理计算 总结 前言 在图像的获取、传输和存储过程常常收到各种噪声的干扰和影响&#xff0c;使得图像的质量下降&#xff0c;为了获得高质量的数字…

读天才与算法:人脑与AI的数学思维笔记20_数学图灵测试

1. 数学图灵测试 1.1. 能不能将这种计算机证明语言翻译成易于与人交流的方式呢&#xff1f; 1.1.1. 剑桥大学的两位数学家蒂莫西高尔斯&#xff08;Timothy Gowers&#xff09;和莫汉加内萨林加姆&#xff08;Mohan Ganesalingam&#xff09;开展了此项研究 1.1.1.1. 他们决…

与Apolo共创生态: Apollo X企业自动驾驶解决方案的亮点

文章目录 前言技术革新的里程碑Apollo X企业自动驾驶解决方案的亮点Application X企业预制套件的多场景覆盖Studio X企业协同工具链的全周期支持第一阶段&#xff1a;上机系统构建第二阶段&#xff1a;POC搭建第三阶段&#xff1a;规模运营小结 共创生态&#xff0c;共享未来共…

Mysql数据在磁盘上的存储结构

一. 前言 一行数据的存储格式大致如下所示: 变长字段的长度列表&#xff0c;null值列表&#xff0c;数据头&#xff0c;column01的值&#xff0c;column02的值&#xff0c;column0n的值… 二. 变长字段 在MySQL里有一些字段的长度是变长的&#xff0c;是不固定的&#xff0c;…

ContEA阅读笔记

Facing Changes: Continual Entity Alignment for Growing Knowledge Graphs 面对变化&#xff1a;不断增长的知识图谱的持续实体对齐 Abstract 实体对齐是知识图谱(KG)集成中一项基本且重要的技术。多年来&#xff0c;实体对齐的研究一直基于知识图谱是静态的假设&#xff…

人工智能的发展将如何重塑网络安全

微信搜索关注公众号网络研究观&#xff0c;获取更多信息。 人们很容易认为人工智能 (AI) 真正出现是在 2019 年&#xff0c;当时 OpenAI 推出了 ChatGPT 的前身 GPT-2。 但现实却有些不同。人工智能的基础可以追溯到 1950 年&#xff0c;当时数学家艾伦图灵发表了题为“计算机…

微信小程序如何使用svg矢量图标

微信小程序如何使用自定义SVG矢量图标 在微信小程序中&#xff0c;经常会用到小图标来装饰界面&#xff0c;我们常用的方法就是引用第三方的图标&#xff0c;但会存在收费或者找不到合适的图标&#xff0c;这时候我建议可以自行编写svg图标代码&#xff0c;就可以随心所欲的使…

【一起深度学习——kaggle叶子分类】

kaggle 叶子分类 目的&#xff1a;将叶子进行分类。实现步骤&#xff1a;1、数据处理&#xff1a;2、加载数据3、 定义残差块4、定义Resnet模型。5、定义训练以及评估函数&#xff1a;6、开始训练&#xff1a;7、输出结果&#xff1a; 目的&#xff1a;将叶子进行分类。 实现步…

知识图谱:人工智能的“核心驱动力”

知识图谱&#xff1a;人工智能的“核心驱动力” 一、人工智能与知识图谱二、知识图谱的定义与重要性三、知识图谱工程师的薪资情况四、知识图谱的应用领域六、知识图谱的未来展望七、总结 一、人工智能与知识图谱 人工智能&#xff08;AI&#xff09;作为21世纪的前沿技术&…

设备树与/sys/bus/platform/devices与/sys/devices目录关系

设备树与sys/bus/platform/devices sysfs文件系统中/sys/bus/platform/devices下的设备是由设备树生成&#xff0c; 根节点下有compatible的子节点都会在/bus/platform/devices生成节点 总线 I2C、SPI 等控制器会在/bus/platform/devices生成节点 总线 I2C、SPI 节点下的子节点…

牛客网刷题 | BC78 KiKi说祝福语

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 2020年来到了&#…

【Qt】按钮类控件

文章目录 1 :peach:Push Button:peach:2 :peach:Radio Buttion:peach:3 :peach:Check Box:peach:4 :peach:Tool Button:peach: 1 &#x1f351;Push Button&#x1f351; 使⽤ QPushButton 表⽰⼀个按钮&#xff0c;这也是当前我们最熟悉的⼀个控件了&#xff0c;QPushButton …

SOL链DApp智能合约代币质押挖矿分红系统开发

随着区块链技术的不断发展和普及&#xff0c;越来越多的项目开始探索基于区块链的去中心化应用&#xff08;DApp&#xff09;。Solana&#xff08;SOL&#xff09;作为一条高性能、低成本的区块链网络&#xff0c;吸引了众多开发者和项目&#xff0c;其中包括了各种类型的DApp&…

Altium Designer——检查原理图库正确性并生成报告

一、方法&#xff1a; 1.打开原理图库&#xff1a; 2.点击菜单栏的报告选项&#xff1a; 3.选择器件规则检查&#xff1a; 根据需求勾选&#xff0c;一般都是全部勾选&#xff1a; 二、问题&#xff1a; 1.缺少封装会导致什么问题&#xff1a; 1.首先&#xff1a; 封装是…

MWeb Pro for Mac:功能强大的Markdown博客编辑器

MWeb Pro for Mac是一款功能强大的Markdown博客编辑器&#xff0c;专为Mac用户设计&#xff0c;提供了一站式的博客写作和发布体验。这款软件不仅支持Markdown语法&#xff0c;还提供了丰富的编辑和排版功能&#xff0c;让用户能够轻松创建出精美的博客内容。 MWeb Pro的即时预…

重庆事业编5月7号开始报名⚠️报名照需审核

24年第二季度重庆事业编招聘 本次招聘实行网上报名。考生应按照招聘岗位要求&#xff0c;诚信、准确填写报考信息&#xff0c;并按网页提示上传电子材料&#xff08;含电子登记照&#xff0c;jpg格式&#xff0c;20kb以下&#xff09;。招聘方按照岗位报考要求&#xff0c;对考…