Android四大组件通讯指南:Kotlin版组件茶话会

news2025/6/7 11:09:32

        某日,Android王国举办Kotlin主题派对。Activity穿着Jetpack Compose定制礼服,Service戴着协程手表,BroadcastReceiver拿着Flow喇叭,ContentProvider抱着Room数据库入场。它们正愁如何交流,Intent举着"邮差"牌子跳出来:"嘿伙计们,这次我用Kotlin语法糖寄快递!"   

一、Activity:前台明星的优雅社交

        Activity作为门面担当,现在有了新绝活——用Kotlin的简洁语法处理生命周期(再也不用写冗长的onSaveInstanceState了!)

启动Activity的三种优雅姿势

// 1. 标准快递(带lambda的快递单)
startActivity(Intent(this, DetailActivity::class.java).apply {
    putExtra("order_id", "KT2023_888")
}

// 2. 专属VIP通道(避免重复创建)
val intent = Intent(this, SingleTopActivity::class.java).apply {
    flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
}
startActivity(intent)

// 3. 协程风格带回执(等待对方签收)
val resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    if (result.resultCode == RESULT_OK) {
        result.data?.getStringExtra("result")?.let { 
            toast("收到回信:$it")
        }
    }
}

resultLauncher.launch(Intent(this, FeedbackActivity::class.java))

Kotlin参数传递魔法

// 发送方使用apply作用域函数
Intent(this, OrderActivity::class.java).apply {
    putExtra("order_id", "KT2023_888")
    putExtra("items", parcelableItemList) // 传递Parcelable集合
    putExtra("discount", 0.8f)
}.also { startActivity(it) }

// 接收方使用kotlin扩展函数
class OrderActivity : AppCompatActivity() {
    private val orderId by lazy { intent.getStringExtra("order_id") ?: "" }
    private val discount by lazy { intent.getFloatExtra("discount", 1.0f) }
    private val items by lazy { 
        intent.getParcelableArrayListExtra<Item>("items") ?: arrayListOf()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 直接使用属性访问
        Log.d("Order", "处理订单:$orderId 折扣:$discount")
    }
}

Kotlin版Intent参数速记表

操作Kotlin优雅写法
创建IntentIntent(context, Target::class.java)
添加参数apply { putExtra(key, value) }
安全获取Stringintent.getStringExtra(key) ?: ""
安全获取集合intent.getParcelableArrayListExtra<T>(key) ?: arrayListOf()
启动Activityalso { startActivity(it) }

二、Service:后台协程大师

Service现在学会用协程处理后台任务:"我再也不怕ANR了!"(但要注意:Android 12+限制前台服务启动

方式一:StartService(协程版后台任务)
// Activity发送启动命令
val serviceIntent = Intent(this, DownloadService::class.java).apply {
    putExtra("url", "https://example.com/kotlin_video.mp4")
}
ContextCompat.startForegroundService(this, serviceIntent)

// Service使用协程处理
class DownloadService : Service() {
    private val job = SupervisorJob()
    private val scope = CoroutineScope(Dispatchers.IO + job)

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        intent?.getStringExtra("url")?.let { url ->
            scope.launch {
                downloadFile(url) // 协程中执行耗时操作
                stopSelf()
            }
        }
        return START_STICKY
    }

    private suspend fun downloadFile(url: String) {
        // 协程下载逻辑
    }

    override fun onDestroy() {
        job.cancel()
        super.onDestroy()
    }
}
方式二:BindService(Kotlin接口双向通话)
// Activity绑定服务
val connection = object : ServiceConnection {
    override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
        (service as? MusicService.LocalBinder)?.getService()?.let { musicService ->
            musicService.apply {
                play() // 直接调用
                setOnProgressListener { progress -> 
                    updateProgress(progress) 
                }
            }
        }
    }
}
bindService(Intent(this, MusicService::class.java), connection, Context.BIND_AUTO_CREATE)

// Service提供Flow接口
class MusicService : Service() {
    private val _progress = MutableStateFlow(0)
    val progress: StateFlow<Int> = _progress

    inner class LocalBinder : Binder() {
        fun getService() = this@MusicService
    }

    fun play() {
        CoroutineScope(Dispatchers.Default).launch {
            while (isPlaying) {
                delay(1000)
                _progress.update { it + 1 }
            }
        }
    }
}

Kotlin版Service对比

特性协程优势
生命周期通过CoroutineScope管理
线程切换使用Dispatchers.IO/Main
状态更新通过StateFlow自动更新UI
错误处理协程异常处理器统一捕获

三、BroadcastReceiver:Flow化广播站

BroadcastReceiver扔掉大喇叭:"我现在用Flow收集广播,环保又高效!"

案例:协程监听网络变化
// 使用Flow包装广播
class NetworkStateFlow(context: Context) : Flow<Boolean> {
    private val contextRef = WeakReference(context)
    
    override suspend fun collect(collector: FlowCollector<Boolean>) {
        val context = contextRef.get() ?: return
        
        val receiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                val isConnected = context?.let { ctx ->
                    (ctx.getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager)
                        .activeNetworkInfo?.isConnected == true
                } ?: false
                collector.emit(isConnected)
            }
        }
        
        context.registerReceiver(receiver, IntentFilter(CONNECTIVITY_ACTION))
        try {
            awaitCancellation() // 等待流取消
        } finally {
            context.unregisterReceiver(receiver)
        }
    }
}

// Activity中优雅收集
lifecycleScope.launch {
    NetworkStateFlow(this@MainActivity).collect { isConnected ->
        binding.networkStatus.text = if (isConnected) "在线" else "离线"
    }
}

四、ContentProvider:Room数据库管家

ContentProvider举着Room牌咖啡:"我现在用Kotlin符号查询数据,香醇又高效!"

案例:使用Room进行组件通讯
// 定义数据库
@Database(entities = [User::class], version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

// DAO接口使用Kotlin协程
@Dao
interface UserDao {
    @Insert
    suspend fun insert(user: User)
    
    @Query("SELECT * FROM user")
    fun getAll(): Flow<List<User>>
}

// Activity中观察数据变化
class UserActivity : AppCompatActivity() {
    private val db by lazy {
        Room.databaseBuilder(applicationContext, AppDatabase::class.java, "user.db").build()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        lifecycleScope.launch {
            db.userDao().getAll().collect { users ->
                // 自动更新UI
                binding.userList.adapter = UserAdapter(users)
            }
        }
        
        // Service更新数据
        Intent(this, SyncService::class.java).also { 
            startService(it)
        }
    }
}

// Service更新数据
class SyncService : Service() {
    private val db by lazy { 
        Room.databaseBuilder(applicationContext, AppDatabase::class.java, "user.db").build()
    }
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        CoroutineScope(Dispatchers.IO).launch {
            val newUser = User(name = "Kotlin开发者")
            db.userDao().insert(newUser)
        }
        return START_NOT_STICKY
    }
}

组件协作实战:新闻阅读App

// 场景:Activity启动Service获取新闻,Service保存到数据库,广播通知更新,ContentProvider提供数据

// 1. Activity启动服务
val serviceIntent = Intent(this, NewsService::class.java).apply {
    putExtra("category", "technology")
}
ContextCompat.startForegroundService(this, serviceIntent)

// 2. Service获取数据并保存
class NewsService : Service() {
    private val db by lazy { NewsDatabase.get(applicationContext) }
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val category = intent?.getStringExtra("category") ?: "general"
        
        CoroutineScope(Dispatchers.IO).launch {
            val news = NewsApi.fetch(category) // 网络请求
            db.newsDao().insertAll(news)
            
            // 发送粘性广播通知更新
            sendBroadcast(Intent("NEWS_UPDATED").apply {
                putExtra("count", news.size)
            })
        }
        
        return START_STICKY
    }
}

// 3. Activity接收广播更新UI
private val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        if (intent?.action == "NEWS_UPDATED") {
            val count = intent.getIntExtra("count", 0)
            binding.newsCount.text = "更新了${count}条新闻"
            
            // 从ContentProvider加载数据
            lifecycleScope.launch {
                db.newsDao().getLatest().collect { news ->
                    binding.newsList.adapter = NewsAdapter(news)
                }
            }
        }
    }
}

override fun onStart() {
    super.onStart()
    registerReceiver(receiver, IntentFilter("NEWS_UPDATED"))
}

组件通讯黄金法则:Kotlin版

  1. Intent快递法则:用apply{}打包数据,用let{}安全拆包

  2. 协程管理法则:Service用CoroutineScope管理任务,Activity用lifecycleScope收集数据

  3. Flow更新法则:用StateFlow替代回调,用collect自动更新UI

  4. Room数据库法则:DAO返回Flow,实现跨组件实时同步

  5. 广播进化法则:用Flow包装传统广播,实现响应式接收

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

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

相关文章

AudioRelay 0.27.5 手机充当电脑音响

—————【下 载 地 址】——————— 【​本章下载一】&#xff1a;https://pan.xunlei.com/s/VOS4MvfPxrnfS2Zu_YS4egykA1?pwdi2we# 【​本章下载二】&#xff1a;https://pan.xunlei.com/s/VOS4MvfPxrnfS2Zu_YS4egykA1?pwdi2we# 【百款黑科技】&#xff1a;https://uc…

NVIDIA Dynamo:数据中心规模的分布式推理服务框架深度解析

NVIDIA Dynamo&#xff1a;数据中心规模的分布式推理服务框架深度解析 摘要 NVIDIA Dynamo是一个革命性的高吞吐量、低延迟推理框架&#xff0c;专为在多节点分布式环境中服务生成式AI和推理模型而设计。本文将深入分析Dynamo的架构设计、核心特性、代码实现以及实际应用示例&…

第十三节:第四部分:集合框架:HashMap、LinkedHashMap、TreeMap

Map集合体系 HashMap集合的底层原理 HashMap集合底层是基于哈希表实现的 LinkedHashMap集合的底层原理 TreeMap集合的底层原理 代码&#xff1a; Student类 package com.itheima.day26_Map_impl;import java.util.Objects;public class Student implements Comparable<Stu…

Spring AI之RAG入门

目录 1. 什么是RAG 2. RAG典型应用场景 3. RAG核心流程 3.1. 检索阶段 3.2. 生成阶段 4. 使用Spring AI实现RAG 4.1. 创建项目 4.2. 配置application.yml 4.3. 安装ElasticSearch和Kibana 4.3.1. 安装并启动ElasticSearch 4.3.2. 验证ElasticSearch是否启动成功 …

应用案例 | 设备分布广, 现场维护难? 宏集Cogent DataHub助力分布式锅炉远程运维, 让现场变“透明”

在日本&#xff0c;能源利用与环保问题再次成为社会关注的焦点。越来越多的工业用户开始寻求更高效、可持续的方式来运营设备、管理能源。而作为一家专注于节能与自动化系统集成的企业&#xff0c;日本大阪的TESS工程公司给出了一个值得借鉴的答案。 01 锅炉远程监控难题如何破…

LINUX 66 FTP 2 ;FTP被动模式;FTP客户服务系统

19&#xff0e; 在vim中将所有 abc 替换为 def&#xff0c;在底行模式下执行©&#xff1f;D A、s/abc/def B、s/abc/def/g C、%s/abc/def D、%s/abc/def/g FTP连接 用户名应该填什么 [rootcode ~]# grep -v ^# /etc/vsftpd/vsftpd.conf anonymous_enableNO local_enab…

网心云 OEC/OECT 笔记(2) 运行RKNN程序

目录 网心云 OEC/OECT 笔记(1) 拆机刷入Armbian固件网心云 OEC/OECT 笔记(2) 运行RKNN程序 RKNN OEC/OEC-Turbo 使用的芯片是 RK3566/RK3568, 这个系列是内建神经网络处理器 NPU 的, 利用 RKNN 可以部署运行 AI 模型利用 NPU 硬件加速模型推理. 要使用 NPU, 首先需要在电脑使…

灵活控制,modbus tcp转ethernetip的 多功能水处理方案

油田自动化和先进的油气行业软件为油气公司带来了诸多益处。其中包括&#xff1a; 1.自动化可以消除多余的步骤、减少人为错误并降低运行设备所需的能量&#xff0c;从而降低成本。 2.油天然气行业不断追求高水平生产。自动化可以更轻松地减少计划外停机时间&#xff0c;从而…

深入了解linux系统—— 进程池

前言&#xff1a; 本篇博客所涉及到的代码以同步到本人gitee&#xff1a;进程池 迟来的grown/linux - 码云 - 开源中国 一、池化技术 在之前的学习中&#xff0c;多多少少都听说过池&#xff0c;例如内存池&#xff0c;线程池等等。 那这些池到底是干什么的呢&#xff1f;池…

光电耦合器:数字时代的隐形守护者

在数字化、自动化高速发展的今天&#xff0c;光电耦合器正以一种低调却不可或缺的方式&#xff0c;悄然改变着我们的生活。它不仅是电子电路中的“安全卫士”&#xff0c;更是连接信号世界的“桥梁”&#xff0c;凭借出色的电气隔离能力&#xff0c;为各类设备提供稳定可靠的信…

手机如何防止ip关联?3种低成本方案

在当今数字化时代&#xff0c;手机已成为人们日常生活中不可或缺的工具&#xff0c;无论是社交、购物、支付还是工作&#xff0c;都离不开手机。然而&#xff0c;随着网络技术的不断发展&#xff0c;网络安全问题也日益突出&#xff0c;其中IP关联问题尤为常见。那么&#xff0…

Pandas和Django的示例Demo

以下是一个结合Pandas和Django的示例Demo&#xff0c;展示如何在Django项目中读取、处理和展示Pandas数据。 Pandas和Django的示例Demo 前置条件&#xff1a; 安装python 基础设置 确保已安装Django和Pandas&#xff1a; pip install django pandasInstalling collected p…

【p2p、分布式,区块链笔记 MESH】Bluetooth蓝牙通信拓扑与操作 BR/EDR(经典蓝牙)和 BLE

目录 1. BR/EDR&#xff08;经典蓝牙&#xff09;网络结构微微网&#xff08;Piconet&#xff09;散射网&#xff08;Scatternet&#xff09;蓝牙 BR/EDR 拓扑结构示意图 2. BLE&#xff08;低功耗蓝牙&#xff09;网络结构广播器与观察者&#xff08;Broadcaster and Observer…

航道无人机巡检系统

随着长江干线、京杭运河等航道智慧化升级提速&#xff0c;传统人工巡检模式已难以满足高频次、大范围、高精度的航道管理需求。无人机凭借其灵活机动、多源感知、高效覆盖等优势&#xff0c;正成为航道巡检的“空中卫士”。本文将结合多地成功案例&#xff0c;从选型标准、技术…

【JVM】Java虚拟机(一)——内存结构

目录 一、简介 二、程序计数器 三、虚拟机栈 栈帧结构&#xff1a; 特点&#xff1a; 四、本地方法栈 特点&#xff1a; 五、堆 堆结构&#xff1a; 特点&#xff1a; 对象分配过程&#xff1a; 六、方法区 方法区结构&#xff1a; 特点&#xff1a; 运行时常量池…

从微积分到集合论(1630-1910)(历史简介)——第4章——现代积分理论的起源(Thomas Hawkins)

第 4 章 现代积分理论的起源 (The Origins of Modern Theories of Integration) Thomas Hawkins 目录 4.1 引言(Introduction) 4.2 Fourier分析与任意函数(Fourier analysis and arbitrary functions) 4.3 对Fourier问题的回应(Responses to Fourier)(1821-1854)…

《Linux运维总结:宝德服务器RAID开启(方式一)》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;Linux运维实战总结 一、背景信息 说明&#xff1a;从客户那里退回来的一台宝德服务器&#xff0c;硬盘不见了&#xff0c;现在需要用两个2T的硬盘…

NY118NY120美光固态闪存NY124NY129

NY118NY120美光固态闪存NY124NY129 美光NY系列固态闪存深度解析&#xff1a;技术、性能与行业洞察 技术架构与核心创新 美光NY系列&#xff08;包括NY118、NY120、NY124、NY129等型号&#xff09;作为企业级存储解决方案的代表作&#xff0c;延续了品牌在3D NAND技术上的深厚…

Odoo 19 路线图(新功能)

Odoo 19 路线图(新功能) Odoo 19 路线图是Odoo官方针对下一版本的发布计划&#xff0c;将在自动化、合规性、用户体验、碳排放报告及本地化等领域推出超过16项新功能。本路线图详细阐述了Odoo 19如何在过往版本基础上进一步提升&#xff0c;助力企业优化销售、财务、运营及客户…

基于NXP例程学习CAN UDS刷写流程

文章目录 前言1.概述1.1 诊断报文 2.协议数据单元(N_PDU)2.1 寻址信息&#xff08;N_AI&#xff09;2.1.1 物理寻址2.1.2 功能寻址2.1.3 常规寻址&#xff08;Normal addressing&#xff09;2.1.4 常规固定寻址&#xff08;Normal fixed addressing&#xff09;2.1.5 扩展寻址&…