【问题标题】:RxJava thread not waiting for resultRxJava 线程不等待结果
【发布时间】:2018-07-04 03:48:01
【问题描述】:

我有这个方法,我试图从 API 中提取数据,然后更新文本视图。一切正常,除了 getRecipeName 在“结束方法”log. .getRecipeName() 使用 RetroFit 从 API 中提取之后没有完成。

我目前正在同时学习 MVP、Dagger、RxJava 和 Butterknife,使用 Mindork's Github page on MVP Architecture

我注释掉了 .subscribeOn 和 .observeOn 以查看结果差异,但没有任何改变。

@Override
public void onRandomButtonClicked() {

    getMvpView().showLoading();
    Log.e(TAG, "Random Method Open");
    getCompositeDisposable().add(getDataManager()
            .getRecipeName()
            //.subscribeOn(getSchedulerProvider().io())
            //.observeOn(getSchedulerProvider().ui())
            .subscribe(new Consumer<String>() {
                @Override
                public void accept(String s) throws Exception {
                    Log.e(TAG, "accept");
                    getMvpView().updateTextView(title);
                }
            }));

    Log.e(TAG, "end method");

}

这是我的 getRecipeName() 方法

@Override
public Observable<String> getRecipeName() {

    /*Create handle for the RetrofitInstance interface*/
    GetDataService service = RetrofitClientInstance.getRetrofitInstance().create(GetDataService.class);
    Call<RecipeList> call = service.getRecipe();
    call.enqueue(new Callback<RecipeList>() {
        @Override
        public void onResponse(@NonNull Call<RecipeList> call, @NonNull retrofit2.Response<RecipeList> response) {


            Log.e("onResponse","Recipe is Successful = " + response.isSuccessful());
            //if response is false then skip to avoid null object reference
            if (response.isSuccessful()) {

                RecipeList drinkRecipe = response.body();

                List<Recipe> recipes = drinkRecipe.getDrinks();
                jokeText = String.valueOf(recipes.size());
                Recipe myRecipe = recipes.get(0);
                jokeText = myRecipe.getStrDrink();

                Log.e("On Response", "Result2: " + jokeText);
            }
            //jokeText = "null";

        }

        @Override
        public void onFailure(Call<RecipeList> call, Throwable t) {
            Log.e("On Response","Failure");
        }
    });

    //return jokeText;
    return Observable.fromCallable(new Callable<String>() {
        @Override
        public String call() throws Exception {
            return jokeText;
        }
    });
}

解决方案

正如 cmets 所说,RxJava Adapter 是正确的选择。我将使用适配器在自己身上发布我的工作代码。我发现很难找到一个可行的例子。

//single api call using retrofit and rxjava
@SuppressLint("CheckResult")
private void getRandomButtonClick(){

    retrofit = RetrofitClientInstance.getRetrofitInstance();

    retrofit.create(GetDataService.class).getRecipe()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(this::handleResults, this::handleError );
}

private void handleResults(RecipeList recipeList) {
    int i = recipeList.getDrinks().size();
    Log.e(TAG, "size is: "+ i);
    Recipe recipe = recipeList.getDrinks().get(0);
    getMvpView().updateTextView(recipe.getStrDrink());
}

 private void handleError(Throwable t){
    Log.e("Observer", "");

}

我的改造客户端实例

 public static Retrofit getRetrofitInstance() {
    if (retrofit == null) {
        retrofit = new retrofit2.Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
    }
    return retrofit;
}

我的界面

public interface GetDataService {

//@Headers({})
@GET("random.php")
Observable<RecipeList> getRecipe();

我找到了一个很好的参考资源来正确实现这一点。 Retrofit Android

【问题讨论】:

  • 你的意思是说结束方法日志后文本视图没有更新?你能确认改造电话正在工作吗?
  • 是的,我删除了它们,但调用显示在日志中。如果我再次调用此方法,它将显示第一次调用的结果。
  • getRecipeName 方法中发生了什么?
  • 添加了 getRecipeName 方法
  • 这就是为什么似乎没有收到任何回复。这是因为你如何创建你的 observable。我会尝试并提出一些解决方案。

标签: android rx-java rx-java2 android-mvp


【解决方案1】:

原因是您的 observable 每次订阅时都会返回 jokeText。调用后立即返回,不会等待你的网络操作。

一种可能的解决方案是使用 RxJavaCallAdapter。链接在这里:https://github.com/square/retrofit/tree/master/retrofit-adapters/rxjava2

它会自动将您的 API 返回转换为 observables。无需手动调用改造请求。只需处理响应并从那里将其转换为您想要的对象。

另一种方法是将整个序列包装在 Observable.createObservable.fromAsync 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-13
    • 2012-07-13
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多