[英]Problems with zip function in rxjava2
看起来 zip 函数没有做任何事情。带有 TAG INSIDE 的请求的 LOG 打印出可观察值,但外面是空的。在 zip 函数中,LOG 调用不做任何事情。 getPosts 返回 ID 列表。 我是 Android 的初学者,所以也许我对 Rxjava 的了解有点多,但显然这是最好的解决方案。本质上, getPosts
返回一个 id 列表,我应该用它来在getStory
中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);
}
}
黑客新闻API
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);
}
您在后台创建一个检索 observable 的故事列表,同时尝试使用在主线程上构造的列表。
为什么不像这样简单地组合getPosts()
呢?
hackerNewsApi.getPosts()
.subscribeOn(Schedulers.io())
.flatMapIterable(posts -> posts)
.flatMap(post -> hackerNewsApi.getStory(post))
.toList()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(allStories -> { /* ... */ }, error -> { /* ... */ });
flatMapIterable
展开您的初始帖子列表,而toList
按某种顺序重新组合它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.