当前位置: 首页 > news >正文

Android 协程间通信

一、Channel(通道)

Channel 是协程间通信的主要方式,类似于阻塞队列但使用挂起而非阻塞。

1. 基本 Channel 使用

// 创建 Channel
val channel = Channel<Int>()// 生产者协程
launch {for (i in 1..5) {channel.send(i) // 发送数据println("发送: $i")}channel.close() // 关闭通道
}// 消费者协程
launch {for (item in channel) { // 接收数据直到通道关闭println("接收: $item")}
}

2. Channel 的容量类型

// 无缓冲通道(默认)- 发送者会挂起直到接收者接收
val rendezvousChannel = Channel<Int>()// 有缓冲通道 - 可以存储指定数量的元素
val bufferedChannel = Channel<Int>(capacity = 10)// 无限容量通道 - 发送永不挂起
val unlimitedChannel = Channel<Int>(Channel.UNLIMITED)// 合并通道 - 最新值覆盖旧值,容量为1
val conflatedChannel = Channel<Int>(Channel.CONFLATED)

3. 实际应用示例

class NetworkManager {private val requestChannel = Channel<Request>(capacity = 100)private val responseChannel = Channel<Response>()init {// 请求处理协程CoroutineScope(Dispatchers.IO).launch {for (request in requestChannel) {val response = processRequest(request)responseChannel.send(response)}}}suspend fun sendRequest(request: Request): Response {requestChannel.send(request)return responseChannel.receive()}private suspend fun processRequest(request: Request): Response {// 网络请求处理delay(100)return Response(request.id, "Success")}
}

二、Flow(流)

Flow 是冷流,更适合响应式数据流场景。

1. 基本 Flow

// 创建 Flow
fun getNumbers(): Flow<Int> = flow {for (i in 1..5) {delay(100)emit(i) // 发射数据}
}// 收集 Flow
lifecycleScope.launch {getNumbers().collect { value ->println("收到: $value")}
}

2. StateFlow(状态流)

class UserViewModel : ViewModel() {// 私有可变状态private val _uiState = MutableStateFlow<UiState>(UiState.Loading)// 公开只读状态val uiState: StateFlow<UiState> = _uiState.asStateFlow()fun loadData() {viewModelScope.launch {_uiState.value = UiState.Loadingtry {val data = fetchData()_uiState.value = UiState.Success(data)} catch (e: Exception) {_uiState.value = UiState.Error(e.message)}}}
}// Activity/Fragment 中收集
lifecycleScope.launch {viewModel.uiState.collect { state ->when (state) {is UiState.Loading -> showLoading()is UiState.Success -> showData(state.data)is UiState.Error -> showError(state.message)}}
}

3. SharedFlow(共享流)

class EventBus {private val _events = MutableSharedFlow<Event>(replay = 0,        // 新订阅者收到的历史事件数extraBufferCapacity = 10  // 额外缓冲容量)val events: SharedFlow<Event> = _events.asSharedFlow()suspend fun emit(event: Event) {_events.emit(event)}
}// 使用示例
class MainActivity : AppCompatActivity() {private val eventBus = EventBus()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 订阅事件lifecycleScope.launch {eventBus.events.collect { event ->handleEvent(event)}}// 发送事件lifecycleScope.launch {eventBus.emit(Event.UserLoggedIn("user123"))}}
}

三、Deferred(延迟值)

用于协程间传递单个异步结果。

// 创建 Deferred
val deferred: Deferred<String> = async {delay(1000)"计算结果"
}// 等待结果
launch {val result = deferred.await()println(result)
}

实际应用:并行请求

suspend fun loadUserProfile() {coroutineScope {val userInfo = async { fetchUserInfo() }val userPosts = async { fetchUserPosts() }val userFriends = async { fetchUserFriends() }// 并行执行,等待所有结果val profile = UserProfile(info = userInfo.await(),posts = userPosts.await(),friends = userFriends.await())displayProfile(profile)}
}

四、CompletableDeferred(可完成的延迟值)

手动控制结果的完成。

class DataLoader {private val resultDeferred = CompletableDeferred<Data>()fun startLoading() {CoroutineScope(Dispatchers.IO).launch {try {val data = loadData()resultDeferred.complete(data) // 手动完成} catch (e: Exception) {resultDeferred.completeExceptionally(e) // 完成异常}}}suspend fun awaitResult(): Data {return resultDeferred.await()}
}

五、Actor 模式(高级)

Actor 是 Channel 的封装,用于状态管理。

sealed class CounterMsg
object Increment : CounterMsg()
object Decrement : CounterMsg()
class GetValue(val response: CompletableDeferred<Int>) : CounterMsg()fun CoroutineScope.counterActor() = actor<CounterMsg> {var counter = 0for (msg in channel) {when (msg) {is Increment -> counter++is Decrement -> counter--is GetValue -> msg.response.complete(counter)}}
}// 使用
val counter = counterActor()launch {counter.send(Increment)counter.send(Increment)val response = CompletableDeferred<Int>()counter.send(GetValue(response))println("计数: ${response.await()}")
}

六、协程间通信方式对比

在这里插入图片描述

七、最佳实践建议

1. 选择合适的通信方式

// ✅ UI 状态 - 使用 StateFlow
val uiState: StateFlow<UiState>// ✅ 一次性事件 - 使用 SharedFlow 或 Channel
val events: SharedFlow<Event>// ✅ 数据流转换 - 使用 Flow
fun searchUsers(query: String): Flow<List<User>>// ✅ 并行任务 - 使用 async/await
val result1 = async { fetchData1() }
val result2 = async { fetchData2() }

2. 注意生命周期

// ✅ 绑定生命周期
lifecycleScope.launch {viewModel.uiState.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect { state -> updateUI(state) }
}// ❌ 避免内存泄漏
class MyActivity : AppCompatActivity() {private val scope = CoroutineScope(Dispatchers.Main) // 可能泄漏override fun onDestroy() {super.onDestroy()scope.cancel() // 必须手动取消}
}
  1. 错误处理
launch {try {channel.send(data)} catch (e: CancellationException) {// 协程取消,正常情况throw e} catch (e: Exception) {// 其他异常,记录日志Log.e("TAG", "发送失败", e)}
}
http://www.dtcms.com/a/598633.html

相关文章:

  • 网站建设速度如何解决沧州做网络推广的平台
  • 网站建设系统 网站自助建站系统平湖网站制作
  • asp伪静态网站如何做筛选网站如何做微信支付宝支付宝支付接口
  • 温州苍南网站建设上海十大猎头公司排名
  • 在家做的手工活哪里有网站郑州短视频拍摄制作
  • 做网站好做网站公司职员工资
  • 线程不是独立的!而是同步的!
  • 招商加盟网站推广方案济南做网站要多少钱
  • 做网站apache如何网站建设找超速云建站
  • 网站关联页面如何做大连网龙网络科技
  • 网站推广策划的思路包括哪些内容中国黄页
  • LeetCode hot100:234 回文链表:快慢指针巧判回文链表
  • 合肥网站建设方案服务营销网站搭建建议
  • 【python】生成器
  • 昆明展示型网站开发网站添加百度地图导航
  • 网站地图什么时候提交好广州网站建设推广方法
  • python的网站开发免费软件库下载
  • 阿里云服务器创建网站吗动漫制作专业用什么笔记本电脑
  • 若依 springBoot 配置国际化
  • 十年经验网站开发公司安阳市商祺网络有限责任公司
  • 网络初识~
  • 织梦怎么做中英文网站做网站只做前端可以用吗
  • C 语言17:位操作符 | ^:从二进制编码到大小端
  • 计算机网站php设计代做平台公司和项目公司的区别
  • flowable04网关和变量
  • 设计旅游网站的主色调sem工具是什么
  • 如何降低交互复杂度,减少用户学习成本
  • 交易类网站做支付宝功能淘宝网站代理怎么做
  • 中国建设银行网站如何注册logo设计公司 南京
  • 麒麟桌面操作系统切换到root用户方法