【问题标题】:Observable OnCompleted cannot update UIObservable OnCompleted 无法更新 UI
【发布时间】:2015-04-05 18:12:04
【问题描述】:

我正在尝试 Toast 完成一个服务电话。但是在 onComplete 方法中我收到了这个异常:

java.lang.RuntimeException: 无法在未调用 Looper.prepare() 的线程内创建处理程序

它是从SafeSubscriber#onNext(T args) 抛出的,看起来像这样:

/**
     * Provides the Subscriber with a new item to observe.
     * <p>
     * The {@code Observable} may call this method 0 or more times.
     * <p>
     * The {@code Observable} will not call this method again after it calls either {@link #onCompleted} or
     * {@link #onError}.
     * 
     * @param args
     *          the item emitted by the Observable
     */
    @Override
    public void onNext(T args) {
        try {
            if (!done) {
                actual.onNext(args);
            }
        } catch (Throwable e) {
            // we handle here instead of another method so we don't add stacks to the frame
            // which can prevent it from being able to handle StackOverflow
            Exceptions.throwIfFatal(e);
            // handle errors if the onNext implementation fails, not just if the Observable fails
            onError(e);
        }
    }

这是我的代码中出现问题的代码 sn-p:

 NetworkService.aService()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread()) 
                    .flatmap(anotherCall)
                    .subscribe(new Subscriber<AddCommentResponse>() {
                @Override
                public void onCompleted() {
                    Toast.makeText(...).show();
                    navigateBack();
                }

                // etc. ...

是我无法从 onCompleted 方法更新 UI 的问题吗?或者我应该在哪里处理 UI 操作?

【问题讨论】:

    标签: java android observable rx-java


    【解决方案1】:

    也许anotherCall 在另一个线程上观察。在flatMap 调用之后移动observeOn(在android 主线程上)。

    【讨论】:

      【解决方案2】:

      原来:

      NetworkService.aService()
                          .subscribeOn(Schedulers.io())
                          .observeOn(AndroidSchedulers.mainThread()) 
                          .flatmap(anotherCall)
      

      在此更改之后,它正在工作:

      NetworkService.aService()
                          .flatmap(anotherCall)
                          .subscribeOn(Schedulers.io())
                          .observeOn(AndroidSchedulers.mainThread()) 
      

      【讨论】:

        【解决方案3】:

        NetworkService 在工作线程上。您正在从工作线程调用 makeText(..),它应该从 UI 线程调用。尝试创建一个 Handler 并从它内部进行烘烤。

        ActivityContext.runOnUiThread(new Runnable() { 
          public void run() { 
        Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
          } 
        }); 
        

        【讨论】:

        • 那么也许我应该切换#subscribeOn() 和#observeOn()? --> 那行不通。我只是在尝试你的建议。即使它有效,我为什么要声明#observeOn(AndroidSchedulers.mainThread())???
        • 所以它正在工作。然而就没有更好的解决方案吗?我会接受答案,谢谢,但如果有人能提供更好的答案,我会接受。
        猜你喜欢
        • 2018-11-09
        • 2017-06-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多