【问题标题】:rx-java: Subscribe to Observable in onHandleIntent of IntentServicerx-java:订阅IntentService的onHandleIntent中的Observable
【发布时间】:2014-11-20 08:55:49
【问题描述】:

我遇到了以下无法解决的问题:

我有一个 IntentService,它在 onHandleIntent 方法中执行一些工作。除了此方法中的一些常见内容外,我还必须向后端发出请求并发送所需的信息。众所周知,onHandleIntent 方法在自己的线程中工作,并在执行最后一条命令的那一刻停止。在某些异步操作的情况下 - 结果可能会丢失,因此 google 建议仅在此方法中使用同步操作。

这是我的问题,我没有使用 subscribeOn 和 observeOn,但看起来我的方法在 sep 有效。线程,这对我来说不安全。

这是我的 onHandleIntent 方法的主体,带有 Retrofit(带有 rx.Observable)调用:

Log.d(TAG, "onHandleIntent | started");

...

getAPI().addItem(item).timeout(AppConfig.NETWORK_TIMEOUT, TimeUnit.SECONDS).doOnNext(new Action1<Response<String>>() {
        @Override
        public void call(Response<String> response) {
           //some job
          Log.d(TAG, "doOnNext || call");
        }
    }).retryWhen(new RetryWithSessionRefresh()).subscribe(new Observer<Response<String>>() {
            @Override
            public void onCompleted() {
                Log.d(TAG, "Observer onCompleted");
            }

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

            @Override
            public void onNext(Response<String> response) {
                Log.d(TAG, "Observer onNext");
            }
        });

...

Log.d(TAG, "onHandleIntent | finished");

改造方法getItem(item)为:

 rx.Observable<Response<String>> addItem(@Body ArrayList<Item> item);

最后的结果是:

  • 11-20 00:49:03.512 onHandleIntent |开始
  • 11-20 00:49:03.517 onHandleIntent |完成
  • 11-20 00:49:04.549 doOnNext ||打电话
  • 11-20 00:49:04.549 观察者 onNext
  • 11-20 00:49:04.550 观察者已完成

那么,问题是如何让它在同一个线程中工作?

【问题讨论】:

    标签: android multithreading intentservice retrofit rx-java


    【解决方案1】:

    您始终可以将 RestAdapter 实例使用的 Http Executer 更改为同步的。 Retrofit 在内部使用 Http Executer 来调度Observable。这将允许您在订阅的线程上启动流程。这也意味着你不能使用这个RestAdapter,如果你不打算像 IntentService 那样提供你自己的Thread

    Executor immediateExecuter = new Executor() {
                @Override
                public void execute(Runnable command) {
                    command.run();
                }
            };
    
    ... new RestAdapter.Builder().setExecutors(immediateExecuter, null).build();
    

    我认为你也可以利用 RxJava 提供的工具来解决这个问题。您可以使用toBlocking 将您的Observable 变成BlockingObservable。这将允许您在继续执行代码之前等待您的流完全完成。需要考虑的一件事是,您必须使用 try/catch 块包装整个流程来处理异常,因为现在将抛出流程中未捕获的异常。我想你可以说这会将你的流变成一个重要的命令式语句。

    try {
        getAPI().addItem(item).timeout(AppConfig.NETWORK_TIMEOUT, TimeUnit.SECONDS).doOnNext(new Action1<Response<String>>() {
                @Override
                public void call(Response<String> response) {
                   //some job
                  Log.d(TAG, "doOnNext || call");
                }
            })
            .retryWhen(new RetryWithSessionRefresh())
            .toBlocking()
            .forEach(new Action1<Response<String>>() {
                    @Override
                    public void call(Response<String> s) {
                        Log.d(TAG, "Observer onNext");
                    }
            });
    } catch (WhatEverExceptionsYourStreamMightThrow e) {
      // Handle error here
    }
    
    ...
    
    Log.d(TAG, "onHandleIntent | finished");
    

    我认为重要的是要注意,每次运行 IntentService 时,第二种解决方案总是涉及 2 个线程。一个线程将由 Retrofit 使用,另一个将是 IntentService 本身。

    【讨论】:

    • 米格尔,非常感谢!只是一个小问题:如果我将 RestAdapter 实例设置为同步 - subscribeOn(Schedulers.io()) 会将我的操作从同步更改为异步吗?
    • 刚刚测试过!它就像一个魅力!因此,让 RestAdapter 同步看起来相当不错,并且每当您需要使用异步请求时,只需使用 subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())!再次感谢您!
    • 是的,应该是这样。你试过了吗?
    • 您好,请问改造调用在哪个线程上运行?我不太明白 Retrofit 衍生出另一个线程的部分,我认为它只是使用调用者线程,如果我们不设置任何调度程序,它就是 IntentService 线程,所以理论上它们在同一个线程中。您能否详细说明“Retrofit 在内部使用 Http Executer 来调度 Observable”?
    • @WenChao 通过在改造 2 之前使用响应式样式签名,默认情况下,如果您在构建 RestAdapter 实例时没有覆盖它,则改造将使用它自己定义的执行程序将您的请求转换为异步请求。看看使用的默认执行器github.com/square/retrofit/blob/parent-1.9.0/retrofit/src/main/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-29
    • 2014-04-14
    相关资源
    最近更新 更多