Android 使用Kotlin协同路由替换Firebase消息的LocalBroadcastManager
在Android上使用时,通常需要将传入的推送通知通知当前的Android 使用Kotlin协同路由替换Firebase消息的LocalBroadcastManager,android,firebase,kotlin,kotlin-coroutines,Android,Firebase,Kotlin,Kotlin Coroutines,在Android上使用时,通常需要将传入的推送通知通知当前的活动。推荐的方法之一是使用从FirebaseMessagingService实现向活动发送意图 但是,自版本1.1.0-alpha01(2018-12-17)起: LocalBroadcastManager是一个应用程序范围的事件总线,包含应用程序中的层冲突:任何组件都可以侦听来自任何其他组件的事件。您可以将LocalBroadcastManager的使用替换为其他可观察模式的实现,具体取决于您的用例,合适的选项可能是流或反应流 虽然这
活动
。推荐的方法之一是使用从FirebaseMessagingService
实现向活动发送意图
但是,自版本1.1.0-alpha01(2018-12-17)起:
LocalBroadcastManager是一个应用程序范围的事件总线,包含应用程序中的层冲突:任何组件都可以侦听来自任何其他组件的事件。您可以将LocalBroadcastManager
的使用替换为其他可观察模式的实现,具体取决于您的用例,合适的选项可能是流或反应流
虽然这个类很可能会在一段时间内保持可用,但无论如何我都想开始清理我们的应用程序,所以我想在Google真正删除旧方法之前迁移到更好的应用程序
目前,这些本地广播在我们的应用程序中有两个主要角色:
使用推送通知中的新数据更新UI。其工作方式是,每个关心传入推送数据的活动
都有一个广播接收器,用于侦听适当的消息并更新自己的视图数据
如果服务器发送结束会话的通知,则强制用户注销。这适用于具有广播接收器实例的每个活动,广播接收器侦听注销事件、结束活动并启动登录活动
在我看来,这些用例与它们建议的两个备选方案都有问题:
LiveData
最容易在活动
或片段
中作为ViewModel
的一部分使用。但是,ViewModel
仅用于直接处理UI的类。从firebasemsagingservice
中访问ViewModel
需要一个难看的技巧,从架构的角度来看,这是一个非常糟糕的主意。另外,不同的活动和片段具有不同的ViewModel
对象,我不希望服务需要访问所有这些对象
- 我可以创建一个Kotlin
对象(也称为Singleton),其中包含一组LiveData
属性,让FirebaseMessagingService
从传入消息中更新这些LiveData
对象,并让活动
观察这些更改,并将其复制到自己的ViewModel
的LiveData
属性中。这有两个问题:首先,它要求我为每个数据段拥有两个相同的LiveData
对象,一个在ViewModel
中,另一个在对象中;其次,它不能帮助我处理“注销事件”,因为LiveData
是用来处理不断变化的数据,而不是监听事件流。(我可能可以用这个来处理第二个问题,但这仍然感觉像是一个坏的黑客攻击,因为它并不打算以这种方式工作。)
- 虽然像RxJava这样的反应流可能会满足我的需要,但在过去的几个月里,我已经迫使我的团队学习Kotlin、Android数据绑定、Android ViewModel和其他一些新东西,我认为他们不需要更多。RxJava也是一个需要添加的大东西,我们不打算重写整个应用程序来利用它来证明其添加的合理性
我发现的一个建议是将Kotlin协同程序与Channel
s或Flow
s一起使用。它们可以非常类似于反应流,但是(与RxJava不同)打算与Kotlin一起使用,并从Kotlin对Java的改进中获益。这一选择尤其具有吸引力,因为谷歌已经宣布他们将重点放在Kotlin上,用于Android开发,而不是Java开发
虽然在我看来这是最好的选择,但我没有设法从其他人那里找到任何关于它是否有效以及这种实现是否有副作用和/或缺陷的反馈。我在kotlinx.coroutines
存储库中找到了一个关于需要提供这样一个应用程序示例的信息。虽然我很想提供这样一个例子,但我认为我对它的了解还不够,无法创建一个好的例子,我也不希望我的生产应用程序成为实验品。我也不知道在这种情况下,使用带有Channel
的显式coutroutines还是使用带有Flow
的suspend
更好(或更合适)
总之:
- Kotlin协程及其相关并发结构是处理Android
服务
和活动
之间通信的好方法吗
- 如果是,使用哪个Kotlin类型更有意义,
频道
或流量
协同程序对从一个软件组件到另一个软件组件的数据切换没有真正的帮助。它们使用看起来像是同步的语法帮助处理多个异步工作单元。这是合作的底线。它们类似于JavaScript中的异步/等待语法。虽然您可以使用协程来访问异步源中的数据,但它不会为您提供任何将该数据代理到其他组件的primitve
LiveData可能对您正在尝试的工作非常有用。不要将ViewModel与LiveData混为一谈-它们解决不同的问题。虽然您认为ViewModel应该只由处理UI的代码访问是正确的,但该准则并没有扩展到LiveData。公开反映FirebaseMessagingService中当前数据的LiveData是完全合理的,这些数据稍后由ViewModel拾取、转换并传递给视图。此LiveData可以是单例数据,也可以通过whatev获得