[Android]四大组件简介

news2025/4/8 19:33:32

在 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.AppCompatActivity

class 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.Log

class MyService : Service() {

    // 当服务被创建时调用
    override fun onCreate() {
        super.onCreate()
        Log.d("MyService", "服务已创建")
    }

    // 每次服务启动时调用
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d("MyService", "服务正在运行")
        // 如果我们希望服务在终止后重启,则返回 START_STICKY
        return START_STICKY
    }

    // 当服务被销毁时调用
    override fun onDestroy() {
        super.onDestroy()
        Log.d("MyService", "服务已销毁")
    }

    // 当其他组件想要绑定服务时调用
    override fun onBind(intent: Intent): IBinder? {
        // 本示例不提供绑定功能,因此返回 null
        return 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.Toast

class 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.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private lateinit var networkChangeReceiver: BroadcastReceiver

    override 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.Uri

class 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 ... >
    <provider
        android: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.coloradmin.cn/o/1647506.html

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

相关文章

青春送温暖 立夏寄真情

&#xff08;通讯员&#xff1a;赵灿飞 图&#xff1a;杨美、孙红浪&#xff09; 在青春洋溢的五月&#xff0c;为传承中华民族尊老敬老的传统美德&#xff0c;促进当代青年与老人的跨代交流&#xff0c;增强青年的社会责任感和使命感&#xff0c;传递正能量和关爱困难群体…

组播应用:SW1、SW2、RT1、RT2、AC1运行PIM-SM

SW1、SW2、RT1、RT2、AC1运行PIM-SM,SW1 Vlan10为C-BSR和C-RP;SW1产品网络(PC1)启用组播,用VLC工具串流播放视频文件“1.mp4”,模拟组播源,设置此视频循环播放,组地址232.1.1.1,端口1234,实现总公司和分公司收看视频,用PC2测试。 一、SW1、SW2、RT1、RT2、AC1配置如…

功能全面的外发文件控制方案,拿走不谢

在日常办公中&#xff0c;很多企业往往只采取各种措施来确保存储数据的安全&#xff0c;却忽略了文件外发的安全。因此企业由于自身的安全防护机制不严谨&#xff0c;引发的数据安全事件频发&#xff0c;经常导致严重的经济损失。使用较多的外发方式有邮件、IM通讯工具、网盘、…

docker的commit命令使用制作镜像

docker run -it ubuntu 最基础的ubuntu启动后安装vim 的命令 apt-get update apt-get -y install vim docker commit -m"my_test_ubuntu" -a"za" 80977284a998 atljw/myubuntu:1.0 将本地镜像推送到阿里云 首先登录阿里云服务-控制台 记得一定要设定设…

鸢尾花分类-pytorch实现

前言 本文用pytorch实现了鸢尾花分类&#xff0c;数据不多&#xff0c;只做代码展示用&#xff0c;后续有升级版本。 代码 -*- coding: utf-8 -*- File : main.py Author: Shanmh Time : 2024/05/06 上午9:37 Function&#xff1a;import torch from sklearn import datase…

uniapp生成二维码(uQRCode)与自定义绘制样式与内容

二维码生成使用了一款基于Javascript环境开发的插件 uQRCode &#xff0c;它不仅适用于uniapp&#xff0c;也适用于所有Javascript运行环境的前端应用和Node.js。 uQRCode 插件地址&#xff1a;https://ext.dcloud.net.cn/plugin?id1287 目录 1、npm安装 2、通过import引…

fabric搭建生产网络

fabric搭建生产网络 一、生成组织结构与身份证书 解包 hyperledger-fabric-linux-amd64-2.5.0.tar.gz 1.1、crypto-config.yaml配置文件 ./bin/cryptogen showtemplate > crypto-config.yaml 将crypto-config.yaml内容修改为&#xff1a; # -------------------------…

pygame实现鼠标绘制并调节画笔大小

pygame实现鼠标绘制并调节画笔大小 pygame介绍调节画笔大小鼠标绘制效果 pygame介绍 Pygame是一个开源的Python库&#xff0c;专为电子游戏开发而设计。它建立在SDL&#xff08;Simple DirectMedia Layer&#xff09;的基础上&#xff0c;允许开发者使用Python这种高级语言来实…

微信个人号开发api接口-视频号矩阵接口-VIdeosApi

友情链接&#xff1a;VIdeosApi 获取用户主页 接口地址&#xff1a; http://api.videosapi.com/finder/v2/api/finder/userPage 入参 { "appId": "{{appid}}", "lastBuffer": "", "toUserName": "v2_060000231003b2…

03、 Kafaka单机环境部署

03、 Kafka单机环境部署 1、 Docker 安装单机版本搭建 &#xff08;1&#xff09;安装Zookeeper docker pull zookeeper&#xff08;2&#xff09;启动zookeeper docker run -d --name zookeeper -p 2181:2181 zookeeper&#xff08;3&#xff09;安装 Kafka docker pull …

酷开科技线上出游,用酷开系统云逛博物馆!

五一假期&#xff0c;当全国各地的旅游景点迎来人潮高峰期时&#xff0c;酷开科技为那些寻求宁静假期体验的消费者带来了一个独特的解决方案——“云逛博物馆”。通过酷开系统&#xff0c;消费者可以在家中的电视上&#xff0c;体验维也纳艺术史博物馆的沉浸式画展&#xff0c;…

AI图书推荐:Zapier和AI融合来自动化业务流程

这本书《Zapier和AI融合来自动化业务流程》&#xff08;Automate It with Zapier and Generative AI&#xff09;由Kelly Goss撰写&#xff0c;这本书是为想要使用Zapier和AI集成功能来自动化重复性任务、提高生产力的微型、小型或中型企业的业务所有者、运营经理和团队准备的。…

抖音爆火的QQ价格评估前端源码

最近抖音很火直播给别人测qq价值多少&#xff0c;这个源码只有前端&#xff0c; 包含激活码验证页&#xff0c;评估页 源码免费下载地址抄笔记 (chaobiji.cn)

【新手入门】Github与Git使用教程

Github与Git 一、Github基础教程 1.1 基本操作 点击代码文件可以直接查看文件的内容&#xff0c;支持在线修改文件&#xff0c;只需要点击(文件内容)右上角的编辑按钮即可进行编辑。 README.md一般介绍项目的功能&#xff0c;用法&#xff0c;注意事项&#xff1b;有时还有…

【LLM第四篇】名词解释:SFT

看到京东的一段开场白&#xff0c;觉得很有道理&#xff1a; 2023年&#xff0c;大语言模型以前所未有的速度和能力改变我们对智能系统的认知&#xff0c;成为技术圈最被热议的话题。但“百模大战”终将走向“落地为王”&#xff0c;如何将大语言模型的强大能力融入实际业务、…

【Django学习笔记(八)】MySQL的数据管理

MySQL的数据管理 前言正文1、新增数据2、删除数据3、修改数据4、查询数据5、案例&#xff1a;员工管理5.1 创建表结构5.1.1 创建数据库5.1.2 创建数据表 5.2 Python操作MySQL5.2.1 pymysql 的基本操作步骤5.2.2 优化 pymysql 的基本操作步骤5.2.3 查询数据5.2.4 修改数据5.2.5 …

数据结构之栈的超详细讲解

目录 引言 一.栈的概念 二.栈的结构 三.栈的实现 栈结构的实现 栈操作函数的声明 栈中方法的实现 栈的初始化 栈的销毁 入栈 出栈 取栈顶元素 判断栈中是否为空 获取栈中数据个数 四.测试 代码展示: 结构展示: 五.小结 六.完整代码 Stack.h Stack.c text…

看Diffusion模型如何提升端到端自动驾驶的能力

文章链接&#xff1a;https://openreview.net/pdf?idyaXYQinjOA 自动驾驶领域在分割和规划模型性能方面取得了显著进展&#xff0c;这得益于大量数据集和创新的架构。然而&#xff0c;这些模型在遇到罕见子群&#xff0c;比如雨天条件时&#xff0c;往往表现不佳。获取必要的…

编程入门(六)【Linux系统基础操作二】

读者大大们好呀&#xff01;&#xff01;!☀️☀️☀️ &#x1f525; 欢迎来到我的博客 &#x1f440;期待大大的关注哦❗️❗️❗️ &#x1f680;欢迎收看我的主页文章➡️寻至善的主页 文章目录 &#x1f525;前言&#x1f680;文件与目录的操作命令cd change directory的缩…

RSA理解版本2

RSA原理理解 起源&#xff1a; RSA是一种公钥密码算法&#xff0c;它的名字是由它的三位开发者&#xff0c;即Ron Rivest、Adi Shamir 和 Leonard Adleman 的姓氏的首字母组成的。 简介&#xff1a; RSA加密算法是一种非对称加密算法&#xff0c;在公开密钥加密和电子商业中…