java - rxjava2中的zip函数问题
问题描述
似乎 zip 函数没有做任何事情。带有 TAG INSIDE 的请求日志打印出 observables 但在 OUTSIDE 是空的。在 zip 函数中,LOG 调用不做任何事情。getPosts 返回 id 列表。我是 Android 的初学者,所以也许我比我能用 Rxjava 咀嚼更多,但显然这是最好的解决方案。本质上,getPosts
返回一个 id 列表,我应该用它来编写进一步的请求。getStory
如果有更简单的我渴望听到它。谢谢。
主要活动
package com.example.hackernews;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import static java.lang.Math.min;
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
private List<DataResponse> dataResponses;
private Observable<List<Integer>> ids;
private List<Observable<DataResponse>> requests = new ArrayList<>();
@SuppressLint("CheckResult")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// mRecyclerView = findViewById(R.id.recyclerView);
// mRecyclerView.setHasFixedSize(true);
// mLayoutManager = new LinearLayoutManager(getApplicationContext());
// mRecyclerView.setLayoutManager(mLayoutManager);
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://hacker-news.firebaseio.com/v0/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(client)
.build();
HackerNewsApi hackerNewsApi = retrofit.create(HackerNewsApi.class);
ids = hackerNewsApi.getPosts();
ids.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(id -> {
for (Integer i : id) {
requests.add(hackerNewsApi.getStory(i));
}
Log.e("onSubscribe", "INSIDE " + requests);
}, Throwable::printStackTrace);
Log.e("onSubscribe", "OUTSIDE " + requests);
Observable.zip(
requests,
new Function<Object[], Object>() {
@Override
public Object apply(Object[] objects) throws Exception {
// Objects[] is an array of combined results of completed requests
Log.e("onSubscribe", "YOUR OBJECTS ARE HERE: " + objects);
// do something with those results and emit new event
return new Object();
}
})
// After all requests had been performed the next observer will receive the Object, returned from Function
.subscribe(
// Will be triggered if all requests will end successfully (4xx and 5xx also are successful requests too)
new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
//Do something on successful completion of all requests
Log.e("onSubscribe", "YOUR OBJECTS ARE HERE: " + o);
}
},
// Will be triggered if any error during requests will happen
new Consumer<Throwable>() {
@Override
public void accept(Throwable e) throws Exception {
//Do something on error completion of requests
}
}
);
// mRecyclerView = findViewById(R.id.recyclerView);
// mRecyclerView.setHasFixedSize(true);
// mLayoutManager = new LinearLayoutManager(this);
// Log.e("onSubscribe", "YOUR DATA IS HERE: " + dataResponses);
// mAdapter = new ExampleAdapter(dataResponses);
//
//
// mRecyclerView.setLayoutManager(mLayoutManager);
// mRecyclerView.setAdapter(mAdapter);
}
}
HackerNewsApi
package com.example.hackernews;
import java.util.List;
import io.reactivex.Observable;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
public interface HackerNewsApi {
@GET("askstories.json?print=pretty")
Observable<List<Integer>> getPosts();
@GET("item/{id}.json?print=pretty")
Observable<DataResponse> getStory(@Path("id") Integer id);
}
解决方案
您在后台创建一个故事检索 observables 的列表,并同时尝试使用在主线程上构建的列表。
为什么不简单地作曲getPosts()
呢?
hackerNewsApi.getPosts()
.subscribeOn(Schedulers.io())
.flatMapIterable(posts -> posts)
.flatMap(post -> hackerNewsApi.getStory(post))
.toList()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(allStories -> { /* ... */ }, error -> { /* ... */ });
flatMapIterable
展开您的初始帖子列表并按toList
某种顺序重新组合它们。
推荐阅读
- c# - 从上下文菜单更改 RichTextBox 中选定文本的前景色
- r - R Shiny:重新布局情节注释
- sql-server - SQL创建1到多视图
- python - 获取容器内 python 脚本中的所有 Docker 环境变量
- spring-boot - 如何使用 JUnit 在 Spring Boot 中的公共方法中模拟私有方法
- ajax - 即使使用按钮类型,表单也会在按钮单击时提交
- java - 如何使用 JSON.simple 在 .json 文件中创建多行?
- google-cloud-platform - 在 GCP 中创建 VM 快照不是对主文件夹进行快照
- python - 从每个文本行中获取一个子字符串
- xamarin - Xamarin 表单中的背景音频