You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin 最简实现自定义事件通知MainViewModel的方法

最短实现路径

直接替换MutableStateFlow为MutableSharedFlow即可,完全规避你提到的两个问题,不需要额外写枚举、密封类做事件过滤。

StateFlow的定位是状态持有容器,天生要求必须有初始值,且新订阅者订阅时会立即收到当前最新状态,从设计上就不适合做一次性事件通知;而SharedFlow是专门为事件推送场景设计的,无强制初始值,只有主动发送事件时才会触发订阅者的收集逻辑。

标准实现代码

// MainViewModel.kt
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.launch

class MainViewModel : ViewModel() {
    // 注意:生产环境建议通过构造传入CustomWebViewClient实例,不要在ViewModel内部直接new,便于测试
    private val client = CustomWebViewClient()

    init {
        viewModelScope.launch {
            client.onPageFinished.collect { loadedUrl ->
                // 仅在onPageFinished实际触发时执行,拿到真实加载完成的url
                // 写你的业务逻辑即可
            }
        }
    }
}
// CustomWebViewClient.kt
import android.webkit.WebView
import android.webkit.WebViewClient
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow

class CustomWebViewClient : WebViewClient() {
    // 参数配置说明:
    // replay=0:不给新订阅者重播历史事件,避免订阅时收到旧回调
    // extraBufferCapacity=1:缓冲1个事件,避免事件触发时暂无可收集的协程导致事件丢失
    private val _onPageFinished = MutableSharedFlow<String>(replay = 0, extraBufferCapacity = 1)
    val onPageFinished = _onPageFinished.asSharedFlow()

    override fun onPageFinished(view: WebView?, url: String) {
        // 直接发送真实url,不需要传无意义的空字符串占位
        _onPageFinished.tryEmit(url)
    }
}

如果你根本不需要获取回调里的url参数,直接把MutableSharedFlow的泛型改成Unit即可,发送时调用_onPageFinished.tryEmit(Unit),连参数都不用传。

更极简的轻量实现

如果你不想引入Flow,要最短代码,可以直接用函数类型当回调,没有额外依赖:

class CustomWebViewClient : WebViewClient() {
    // 给个默认空实现,不用做非空判断
    var onPageFinished: (url: String) -> Unit = {}

    override fun onPageFinished(view: WebView?, url: String) {
        onPageFinished(url)
    }
}

// ViewModel中使用
class MainViewModel : ViewModel() {
    private val client = CustomWebViewClient().apply {
        onPageFinished = { loadedUrl ->
            // 业务逻辑
        }
    }
}

这种写法代码量最少,性能开销最低,只需要注意:如果WebView的生命周期长于ViewModel,要在页面销毁时把回调置空,避免内存泄漏。


内容的提问来源于stack exchange,提问作者Viewed

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 18:27:33