I'm totally new to RxJava
and I've spent all day understanding it, I'm tying to think how to solve this problem:
I have one object, fetched by Retrofit
, it contains two ArrayLists
, I have to process every ArrayList differently. Currently it looks like:
apiService.getUser(token).enqueue(new Callback<User>() {
@Override
public void onResponse(Response<User> response) {
final User user = response.body();
for (Skill s : user.getSkills()) {
// process here first ArrayList
}
for (OrganizerAction o : user.getOrganizerActions()) {
// process here second ArrayList
}
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
UPDATE:
public class User {
// fields
@SerializedName("organizer_actions")
@Expose
private List<OrganizerAction> mOrganizerActions;
@SerializedName("skills")
@Expose
private List<Skill> mSkills;
public List<OrganizerAction> getOrganizerActions() {
return mOrganizerActions;
}
public List<Skill> getSkills() {
return mSkills;
}
}
Thanks,
Anton
This answer is for Retrofit 2.0.0-beta, which is what you appear to be using. Also, you didn't give your POJO or service definitions, so going to use a general GitHub API example as a guide, modify to match your specify data.
First step is to convert your service definition to use Observable
instead of Call
.
public interface GitHubService {
@GET("/users/{user}")
Observable<User> getUser(@Path("user") String user);
}
Where User
is
public class User {
public String login;
public int id;
}
Next, add a custom call adapter with to your retrofit builder with addCallAdapterFactory
--
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
Get your service in the usual way --
GitHubService gitHubService = retrofit.create(GitHubService.class);
Next, get your observable and call cache
on it to create an Observable
that will replay the result. From that Observable, you can subscribe multiple times, in your case, you can subscribe twice. Once for each type of data you are interested in, and use the map
function to transform from the User
object to your specific fields. map
allows you to apply function to the data in the observable. See the docs for more details. In this example, we will make two streams. One each for the id
and login
fields.
Observable<User> getUserResult = gitHubService.getUser("octocat").cache(1);
getUserResult.map(new Func1<User, Integer>() {
@Override
public Integer call(User user) {
return user.id;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer id) {
Log.d("Stream 1", "id = " + id);
}
});
getUserResult.map(new Func1<User, String>() {
@Override
public String call(User user) {
return user.login;
}
}).subscribe(new Action1<String>() {
@Override
public void call(String login) {
Log.d("Stream 2", "login = " + login);
}
});
Finally, make sure your gradle file has the needed dependencies,
compile 'io.reactivex:rxjava:1.0.14'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta1'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta1'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta1'
And, not directly related to your question, but if you are going to doing RxJava in Android, I recommend you checkout Retrolambda if you have not already. The above map and subscribe code, and Rx code in general, is more succinct with lambdas.
getUserResult.map(user -> user.id).subscribe(
id -> { Log.d("Stream 1", "id = " + id); }
);
getUserResult.map(user -> user.login).subscribe(
login -> { Log.d("Stream 2", "login = " + login); }
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.