【问题标题】:How to update UI from Android service using RxJava/RxAndroid如何使用 RxJava/RxAndroid 从 Android 服务更新 UI
【发布时间】:2025-11-30 16:05:02
【问题描述】:

我有一个绑定服务负责下载文件,因此它知道下载状态/进度。并且 UI(Fragment 或 Activity)必须显示/更新服务的下载进度。

其实我认为常用的方法是使用BroadcastReciever 或来自Activity 的CallBack。但我在某处听说过使用 RxJava(ReactiveX 编程)和 mediator 类(以及 Dagger 将其注入到服务和活动中),如下所述。

所以我的问题是如何用这些东西来处理 RxJava?任何代码示例?除了使用意图之外,还有其他有效的方法吗?

资源: More efficient way of updating UI from Service than intents?【看第一个答案更新】

【问题讨论】:

  • 个人更喜欢使用Messenger服务:developer.android.com/reference/android/os/Messenger.html
  • 我以为我在这里有一个使用 Messenger 的例子,我猜没有,但这里有一篇很好的帖子详细介绍了它的使用:*.com/questions/4300291/…
  • 只使用“本地绑定服务”模式,不需要任何外部库,这是最快的解决方案
  • 是的,这正是我的意思,但如果您将下载内容存储在一些 sqlite 数据库中,您可以使用 CursorLoader 来查询您的自定义 ContentProvider 并且服务更新/插入/删除您的提供程序,在此情况下不需要任何回调
  • @AmirHoseinKazemNejad 这不是你要找的东西,但也许这篇文章会启发你donnfelker.com/rxjava-with-aidl-services

标签: android android-service rx-java ui-thread rx-android


【解决方案1】:

RxJava/RxAndroid 需要

1) 可观察的 2) 观察者 3) 订阅

计划您需要放置 123

的位置

OBSERVABLES去哪里创建数据,所以在你的情况下SERVICE

OBSERVERS去哪里需要使用(或显示)数据,这就是你的活动

SUBSCRIBE 去任何你可以访问 OBSERVABLE 和 OBSERVER 的地方,所以让我们使用 ACVITITY

程序和代码:

首先, 像这样准备您的 OBSERVABLE 服务

class MyService extends Service {
    static PublishSubject<String> data = PublishSubject.create();

   @Override
   public void onStarCommand(Intent intent,int i, int j){
        # DO THIS ANYWHER WHERE YOU GENERATE DATA 
        data.onNext("Hello");
   }

   public static Observable<String> getObservable(){
      return data;
   }
}

其次, 在 Activity 的 onCreate 中准备您的 OBSERVER(和 OBSERVABLE)

Observable<String> observable = MyService.getObservable();
Observer<String> observer = new Observer<String>() {
        @Override
        public void onCompleted() {
            Log.d(TAG, "onCompleted: ");
        }

        @Override
        public void onError(Throwable e) {
            Log.e(TAG, "onError: ",e);
        }

        @Override
        public void onNext(String text) {
            Log.d(TAG, "DATA reveived here: "+text);
        }
    };

最后 在Activity中同时链接OBSERVER和OBSERVABLE,否则Observable不会响应, 在 onCreate 中再次使用它

observable.subscribe(observer);

DONE,现在即使使用 onNext() 从 Service 触发数据,数据也会到达 Activity

【讨论】:

  • 没有静态字段怎么办?
  • public void onCompleted() 应该是 public void onComplete()。也缺少 onSubscribe() 方法。
  • 当活动/片段被破坏或不活动时应用程序崩溃..如何处理这个?
【解决方案2】:

当某些东西绑定到您的Service 时,您使用的Binder 子类可以公开一个方法,该方法返回一个发出进度数据的Observable

使用这种方法需要注意的是,当Activity 实例不再有效时,您需要释放两个资源:服务连接和可观察订阅。

【讨论】:

  • 你能解释一下你的评论,或者举个例子吗?
  • 错误答案。 Observable 不是序列化对象,所以不确定它是否会起作用,特别是如果服务是为跨进程交互而设计的。不会工作。
  • 跨进程交互不在这个问题的范围内。否则,基本上和通过Binder暴露你的Service实例一样,Service也是不可序列化的。
  • @LeonardoAcevedo,尚未测试,但不应该工作
  • @msangel 对于本地绑定服务应该不需要序列化,你认为这适用于这种情况吗?
最近更新 更多