Pour les choses de réseautage simples, les avantages de RxJava par rapport à Callback sont très limités. Le simple exemple getUserPhoto:
RxJava:
api.getUserPhoto(photoId)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Photo>() {
@Override
public void call(Photo photo) {
// do some stuff with your photo
}
});
Rappeler:
api.getUserPhoto(photoId, new Callback<Photo>() {
@Override
public void onSuccess(Photo photo, Response response) {
}
});
La variante RxJava n'est pas beaucoup mieux que la variante Callback. Pour l'instant, ignorons la gestion des erreurs. Prenons une liste de photos:
RxJava:
api.getUserPhotos(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(new Func1<List<Photo>, Observable<Photo>>() {
@Override
public Observable<Photo> call(List<Photo> photos) {
return Observable.from(photos);
}
})
.filter(new Func1<Photo, Boolean>() {
@Override
public Boolean call(Photo photo) {
return photo.isPNG();
}
})
.subscribe(
new Action1<Photo>() {
@Override
public void call(Photo photo) {
list.add(photo)
}
});
Rappeler:
api.getUserPhotos(userId, new Callback<List<Photo>>() {
@Override
public void onSuccess(List<Photo> photos, Response response) {
List<Photo> filteredPhotos = new ArrayList<Photo>();
for(Photo photo: photos) {
if(photo.isPNG()) {
filteredList.add(photo);
}
}
}
});
Maintenant, la variante RxJava n'est toujours pas plus petite, bien qu'avec Lambdas, elle serait plus proche de la variante Callback. De plus, si vous avez accès au flux JSON, il serait assez étrange de récupérer toutes les photos lorsque vous n'affichez que les fichiers PNG. Ajustez simplement le flux pour qu'il affiche uniquement les fichiers PNG.
Première conclusion
Cela ne rend pas votre base de code plus petite lorsque vous chargez un simple JSON que vous avez préparé pour être au bon format.
Maintenant, rendons les choses un peu plus intéressantes. Supposons que vous souhaitiez non seulement récupérer la photo utilisateur, mais que vous ayez un clone Instagram et que vous souhaitiez récupérer 2 JSON: 1. getUserDetails () 2. getUserPhotos ()
Vous souhaitez charger ces deux JSON en parallèle, et lorsque les deux sont chargés, la page doit être affichée. La variante de rappel deviendra un peu plus difficile: vous devez créer 2 rappels, stocker les données dans l'activité, et si toutes les données sont chargées, afficher la page:
Rappeler:
api.getUserDetails(userId, new Callback<UserDetails>() {
@Override
public void onSuccess(UserDetails details, Response response) {
this.details = details;
if(this.photos != null) {
displayPage();
}
}
});
api.getUserPhotos(userId, new Callback<List<Photo>>() {
@Override
public void onSuccess(List<Photo> photos, Response response) {
this.photos = photos;
if(this.details != null) {
displayPage();
}
}
});
RxJava:
private class Combined {
UserDetails details;
List<Photo> photos;
}
Observable.zip(api.getUserDetails(userId), api.getUserPhotos(userId), new Func2<UserDetails, List<Photo>, Combined>() {
@Override
public Combined call(UserDetails details, List<Photo> photos) {
Combined r = new Combined();
r.details = details;
r.photos = photos;
return r;
}
}).subscribe(new Action1<Combined>() {
@Override
public void call(Combined combined) {
}
});
Nous arrivons quelque part! Le code de RxJava est maintenant aussi gros que l'option de rappel. Le code RxJava est plus robuste; Pensez à ce qui se passerait si nous avions besoin d'un troisième JSON à charger (comme les dernières vidéos)? Le RxJava n'aurait besoin que d'un petit ajustement, tandis que la variante de rappel doit être ajustée à plusieurs endroits (à chaque rappel, nous devons vérifier si toutes les données sont récupérées).
Un autre exemple; nous voulons créer un champ de saisie semi-automatique, qui charge les données à l'aide de Retrofit. Nous ne voulons pas faire un appel Web chaque fois qu'un EditText a un TextChangedEvent. Lorsque vous tapez rapidement, seul le dernier élément doit déclencher l'appel. Sur RxJava, nous pouvons utiliser l'opérateur anti-rebond:
inputObservable.debounce(1, TimeUnit.SECONDS).subscribe(new Action1<String>() {
@Override
public void call(String s) {
// use Retrofit to create autocompletedata
}
});
Je ne vais pas créer la variante Callback mais vous comprendrez que c'est beaucoup plus de travail.
Conclusion: RxJava est exceptionnellement bon lorsque les données sont envoyées sous forme de flux. Le Retrofit Observable pousse tous les éléments du flux en même temps. Ce n'est pas particulièrement utile en soi par rapport à Callback. Mais quand il y a plusieurs éléments poussés sur le flux et à différents moments, et que vous devez faire des choses liées au timing, RxJava rend le code beaucoup plus maintenable.