Android学习之响应式编程

news2025/5/13 6:05:14

本篇基于DeepSeek 搜索结果修改。

一、响应式编程基础认知

1.1 为什么需要响应式编程?

在传统的Android开发中,我们经常会遇到以下痛点:

// 传统方式处理数据变化
button.setOnClickListener {
    // 触发网络请求
    fetchDataFromNetwork { result ->
        // 更新UI
        textView.text = result
        
        // 如果数据依赖其他状态,需要手动管理
        if (result.isNotEmpty()) {
            recyclerView.visibility = View.VISIBLE
        } else {
            recyclerView.visibility = View.GONE
        }
    }
}

这种方式存在以下问题:

  • 多层嵌套导致代码可读性差
  • 手动管理状态变化容易出错
  • 线程切换复杂
  • 难以处理异步数据流

1.2 响应式编程核心概念

1.2.1 数据流

数据流是响应式编程的核心,它可以是:

  • 同步数据流:如集合
  • 异步数据流:如网络请求、传感器数据
1.2.2 观察者模式

观察者模式由以下部分组成:

  • 被观察对象(Observable)
  • 观察者(Observer)
  • 订阅关系(Subscription)
// 简化版观察者模式实现
class Observable<T> {
    private val observers = mutableListOf<Observer<T>>()
    
    fun subscribe(observer: Observer<T>) {
        observers.add(observer)
    }
    
    fun emit(value: T) {
        observers.forEach { it.onNext(value) }
    }
}

interface Observer<T> {
    fun onNext(value: T)
    fun onError(error: Throwable)
    fun onComplete()
}
1.2.3 操作符

操作符用于转换、过滤和组合数据流:

  • map:转换数据
  • filter:过滤数据
  • flatMap:处理嵌套数据流
  • debounce:防抖处理

二、Android响应式编程工具

2.1 LiveData入门

2.1.1 LiveData基础使用

LiveData是Android官方提供的可观察数据持有者类:

// 创建LiveData
val liveData = MutableLiveData<String>()

// 观察LiveData
liveData.observe(this) { value ->
    // 数据变化时更新UI
    textView.text = value
}

// 更新LiveData
liveData.value = "New Value"
2.1.2 LiveData与ViewModel结合

LiveData通常与ViewModel结合使用:

class MyViewModel : ViewModel() {
    private val _data = MutableLiveData<String>()
    val data: LiveData<String> = _data
    
    fun loadData() {
        // 模拟数据加载
        viewModelScope.launch {
            delay(1000)
            _data.value = "Loaded Data"
        }
    }
}

2.2 RxJava深入

2.2.1 RxJava基本概念

RxJava使用Observable和Observer处理数据流:

// 创建Observable
Observable<String> observable = Observable.just("Hello", "RxJava", "World");

// 创建Observer
Observer<String> observer = new Observer<String>() {
    @Override
    public void onSubscribe(Disposable d) {
        // 订阅时调用
    }

    @Override
    public void onNext(String s) {
        // 接收到数据时调用
        Log.d("RxJava", s);
    }

    @Override
    public void onError(Throwable e) {
        // 发生错误时调用
    }

    @Override
    public void onComplete() {
        // 完成时调用
    }
};

// 订阅
observable.subscribe(observer);
2.2.2 RxJava操作符实战

使用操作符处理复杂数据流:

Observable.just("apple", "banana", "cherry")
    .map(fruit -> fruit.toUpperCase())
    .filter(fruit -> fruit.startsWith("B"))
    .subscribe(fruit -> {
        Log.d("RxJava", "Filtered: " + fruit);
    });

2.3 Kotlin Flow实战

2.3.1 Flow基础

Flow是Kotlin协程中的响应式编程库:

// 创建Flow
fun numbers(): Flow<Int> = flow {
    for (i in 1..3) {
        delay(100)
        emit(i)
    }
}

// 收集Flow
viewModelScope.launch {
    numbers()
        .map { it * it }
        .collect { value ->
            Log.d("Flow", "Received: $value")
        }
}
2.3.2 Flow与网络请求

使用Flow处理网络请求:

suspend fun fetchData(): Flow<Data> = flow {
    // 模拟网络请求
    val response = apiService.getData()
    emit(response)
}

三、实战案例进阶

3.1 搜索功能实现对比

3.1.1 传统实现方式
editText.addTextChangedListener(object : TextWatcher {
    override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
    
    override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        // 每次文本变化都触发搜索
        performSearch(s.toString())
    }
    
    override fun afterTextChanged(s: Editable?) {}
})

private fun performSearch(query: String) {
    // 执行搜索
}
3.1.2 使用RxJava实现防抖搜索
RxTextView.textChanges(editText)
    .debounce(300, TimeUnit.MILLISECONDS)
    .filter(text -> text.length() > 2)
    .switchMap(query -> searchApi.search(query.toString())
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
    )
    .subscribe(results -> {
        // 更新UI
    });
3.1.3 使用Flow实现防抖搜索
editText.textChanges()
    .debounce(300)
    .filter { it.length > 2 }
    .mapLatest { query ->
        repository.search(query.toString())
    }
    .flowOn(Dispatchers.IO)
    .onEach { results ->
        // 更新UI
    }
    .launchIn(lifecycleScope)

3.2 多数据源合并

3.2.1 合并本地和远程数据
fun getUsers(): Flow<List<User>> = flow {
    // 先发射本地数据
    emit(localDataSource.getUsers())
    
    // 再发射远程数据
    val remoteUsers = remoteDataSource.getUsers()
    localDataSource.saveUsers(remoteUsers)
    emit(remoteUsers)
}

四、总结

可以看出,Android 的响应式编程范式主要是由观察者模式结合响应式流来实现的。观察者模式作为核心架构,构建起数据生产者与消费者之间的订阅关系,使得数据变化能够及时被关注;响应式流则负责承载数据的流动与处理,通过操作符对数据进行转换、过滤等操作,实现复杂业务逻辑的编排。

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

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

相关文章

Nacos源码—8.Nacos升级gRPC分析六

大纲 7.服务端对服务实例进行健康检查 8.服务下线如何注销注册表和客户端等信息 9.事件驱动架构源码分析 一.处理ClientChangedEvent事件 也就是同步数据到集群节点&#xff1a; public class DistroClientDataProcessor extends SmartSubscriber implements DistroDataSt…

SpringBoot 自动装配原理 自定义一个 starter

目录 1、pom.xml 文件1.1、parent 模块1.1.1、资源文件1.1.1.1、resources 标签说明1.1.1.2、从 Maven 视角&#xff1a;资源处理全流程​ 1.1.2、插件 1.2、dependencies 模块 2、启动器3、主程序3.1、SpringBootApplication 注解3.2、SpringBootConfiguration 注解3.2.1、Con…

【C++进阶篇】多态

深入探索C多态&#xff1a;静态与动态绑定的奥秘 一. 多态1.1 定义1.2 多态定义及实现1.2.1 多态构成条件1.2.1.1 实现多态两个必要条件1.2.1.2 虚函数1.2.1.3 虚函数的重写/覆盖1.2.1.4 协变1.2.1.5 析构函数重写1.2.1.6 override和final关键字1.2.1.7 重载/重写/隐藏的对⽐ 1…

《AI大模型应知应会100篇》第60篇:Pinecone 与 Milvus,向量数据库在大模型应用中的作用

第60篇&#xff1a;Pinecone与Milvus&#xff0c;向量数据库在大模型应用中的作用 摘要 本文将系统比较Pinecone与Milvus两大主流向量数据库的技术特点、性能表现和应用场景&#xff0c;提供详细的接入代码和最佳实践&#xff0c;帮助开发者为大模型应用选择并优化向量存储解…

Java学习手册:客户端负载均衡

一、客户端负载均衡的概念 客户端负载均衡是指在客户端应用程序中&#xff0c;根据一定的算法和策略&#xff0c;将请求分发到多个服务实例上。与服务端负载均衡不同&#xff0c;客户端负载均衡不需要通过专门的负载均衡设备或服务&#xff0c;而是直接在客户端进行请求的分发…

Docker私有仓库实战:官方registry镜像实战应用

抱歉抱歉&#xff0c;离职后反而更忙了&#xff0c;拖了好久&#xff0c;从4月拖到现在&#xff0c;在学习企业级方案Harbor之前&#xff0c;我们先学习下官方方案registry&#xff0c;话不多说&#xff0c;详情见下文。 注意&#xff1a;下文省略了基本认证 TLS加密&#xff…

Redis+Caffeine构建高性能二级缓存

大家好&#xff0c;我是摘星。今天为大家带来的是RedisCaffeine构建高性能二级缓存&#xff0c;废话不多说直接开始~ 目录 二级缓存架构的技术背景 1. 基础缓存架构 2. 架构演进动因 3. 二级缓存解决方案 为什么选择本地缓存&#xff1f; 1. 极速访问 2. 减少网络IO 3…

【计算机网络】NAT技术、内网穿透与代理服务器全解析:原理、应用及实践

&#x1f4da; 博主的专栏 &#x1f427; Linux | &#x1f5a5;️ C | &#x1f4ca; 数据结构 | &#x1f4a1;C 算法 | &#x1f152; C 语言 | &#x1f310; 计算机网络 上篇文章&#xff1a;以太网、MAC地址、MTU与ARP协议 下篇文章&#xff1a;五种IO模型与阻…

Python训练打卡Day21

常见的降维算法&#xff1a; # 先运行预处理阶段的代码 import pandas as pd import pandas as pd #用于数据处理和分析&#xff0c;可处理表格数据。 import numpy as np #用于数值计算&#xff0c;提供了高效的数组操作。 import matplotlib.pyplot as plt #用于绘…

node .js 启动基于express框架的后端服务报错解决

问题&#xff1a; node .js 用npm start 启动基于express框架的后端服务报错如下&#xff1a; /c/Program Files/nodejs/npm: line 65: 26880 Segmentation fault "$NODE_EXE" "$NPM_CLI_JS" "$" 原因分析&#xff1a; 遇到 /c/Program F…

并发笔记-信号量(四)

文章目录 背景与动机31.1 信号量&#xff1a;定义 (Semaphores: A Definition)31.2 二元信号量 (用作锁) (Binary Semaphores - Locks)31.3 用于排序的信号量 (Semaphores For Ordering)31.4 生产者/消费者问题 (The Producer/Consumer (Bounded Buffer) Problem)31.5 读写锁 (…

【HTOP 使用指南】:如何理解主从线程?(以 Faster-LIO 为例)

htop 是 Linux 下常用的进程监控工具&#xff0c;它比传统的 top 更友好、更直观&#xff0c;尤其在分析多线程或多进程程序时非常有用。 以下截图就是在运行 Faster-LIO 实时建图时的 htop 状态展示&#xff1a; &#x1f50d; 一、颜色说明 白色&#xff08;或亮色&#xf…

数据同步DataX任务在线演示

数据同步DataX任务在线演示 1. 登录系统 访问系统登录页面&#xff0c;输入账号密码完成身份验证。 2. 环境准备 下载datax安装包&#xff0c;并解压到安装目录 3. 集群创建 点击控制台-多集群管理 计算组件添加DataX 配置DataX引擎,Datax.local.path填写安装目录。 4. …

telnetlib源码深入解析

telnetlib 是 Python 标准库中实现 Telnet 客户端协议的模块&#xff0c;其核心是 Telnet 类。以下从 协议实现、核心代码逻辑 和 关键设计思想 三个维度深入解析其源码。 一、Telnet 协议基础 Telnet 协议基于 明文传输&#xff0c;通过 IAC&#xff08;Interpret As Command…

TAPIP3D:持久3D几何中跟踪任意点

简述 在视频中跟踪一个点&#xff08;比如一个物体的某个特定位置&#xff09;听起来简单&#xff0c;但实际上很复杂&#xff0c;尤其是在3D空间中。传统方法通常在2D图像上跟踪像素&#xff0c;但这忽略了物体的3D几何信息和摄像机的运动&#xff0c;导致跟踪不稳定&#xf…

uniapp 生成海报二维码 (微信小程序)

先下载qrcodenpm install qrcode 调用 community_poster.vue <template><view class"poster-page"><uv-navbar title"物业推广码" placeholder autoBack></uv-navbar><view class"community-info"><text clas…

16.Excel:数据收集

一 使用在线协作工具 简道云。 excel的在线表格协作在国内无法使用&#xff0c;而数据采集最需要在线协作。 二 使用 excel 1.制作表格 在使用excel进行数据采集的时候&#xff0c;会制作表头给填写人&#xff0c;最好还制作一个示例。 1.输入提示 当点击某个单元格的时候&am…

AI系列:智能音箱技术简析

AI系列&#xff1a;智能音箱技术简析 智能音箱工作原理详解&#xff1a;从唤醒到执行的AIPipeline-CSDN博客 挑战真实场景对话——小爱同学背后关键技术深度解析 - 知乎 (zhihu.com) AI音箱的原理&#xff0c;小爱同学、天猫精灵、siri。_小爱同学原理-CSDN博客 智能音箱执行步…

BUUCTF——Ezpop

BUUCTF——Ezpop 进入靶场 给了php代码 <?php //flag is in flag.php //WTF IS THIS? //Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95 //And Crack It! class Modifier {protected $v…

三、Hadoop1.X及其组件的深度剖析

作者&#xff1a;IvanCodes 日期&#xff1a;2025年5月7日 专栏&#xff1a;Hadoop教程 一、Hadoop 1.X 概述 &#xff08;一&#xff09;概念 Hadoop 是 Apache 开发的分布式系统基础架构&#xff0c;用 Java 编写&#xff0c;为集群处理大型数据集提供编程模型&#xff0c;…