Quand je vois pour la première fois la source écrite en RxJava, le flux du processus est difficile à suivre, Il y a de nombreux cas où nous ne pouvons pas comprendre la partie de la logique que nous voulons à l'origine comprendre. (Au moins j'étais ...)
Cet article présente les principales classes et méthodes de RxJava,
En suivant le processus tout en déplaçant réellement le code, Lisez les lecteurs! RxJava ».
―― Qu'est-ce que RxJava est délicieux?
** "Je ne comprends pas la signification de ce chiffre! !! 』** Je te l'enverrai.
--Java8 (ou supérieur)
Dans le cas de gradle, écrivez simplement ce qui suit.
build.gradle
repositories {
mavenCentral()
maven { url 'https://oss.jfrog.org/libs-snapshot' }
}
dependencies {
compile 'io.reactivex.rxjava2:rxjava:2.2.0-SNAPSHOT'
}
Pour les autres personnes, veuillez vous référer à ce qui suit. https://github.com/ReactiveX/RxJava
De plus, lambda est utilisé comme connaissance préalable. Si vous êtes inquiet à propos de lambda, veuillez en savoir plus sur ce qui suit. https://qiita.com/sanotyan1202/items/64593e8e981e8d6439d3
Un exemple de code est ci-dessous. Cela fonctionne tel quel, alors essayez-le.
https://github.com/youyanntoto/RxJavaSample
En outre, ce volume expliquera principalement l'exemple de code.
Main.java
public static void main(String[] args) {
System.out.println("*** main start ***");
RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
System.out.println(tokyoWeather);
System.out.println(yokohamaWeather);
System.out.println(nagoyaWeather);
System.out.println("*** main end ***");
}
RestUtil.java
public static Weather getWeather(Place place) {
Weather weather;
//Obtenez la météo appropriée pour chaque endroit
switch (place) {
case TOKYO:
weather = Weather.SUNNY;
break;
case YOKOHAMA:
weather = Weather.RAINY;
break;
case NAGOYA:
weather = Weather.WINDY;
break;
default:
weather = Weather.SUNNY;
break;
}
try {
//Temps de traitement de la communication 500~Faites que cela prenne 999 ms
Thread.sleep(new Random().nextInt(500) + 500);
} catch (InterruptedException e) {
// nop
}
return weather;
}
Voir la classe principale. Effectuer une communication de repos (RestUtil # getWeather (RestUtil.Place)) Exécute le processus d'acquisition de la météo (RestUtil.Weather) dans la zone spécifiée.
Comme vous pouvez le voir dans la classe RestUtil, le processus de communication lui-même est un mannequin.
RestUtil.getWeather prend désormais 500 à 999 ms chacun. Donc, si vous exécutez Main.java, cela prendra environ 1500-3000ms de 500-999ms x 3.
Maintenant, réactivons le code ci-dessus.
CompletableSample.java
public static void main(String[] args) {
System.out.println("*** main start ***");
Completable.create(emitter -> {
RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
System.out.println(tokyoWeather);
System.out.println(yokohamaWeather);
System.out.println(nagoyaWeather);
emitter.onComplete();
}).subscribe(() -> {
System.out.println("Complete!!");
}, throwable -> {
System.out.println("Error!!");
throwable.printStackTrace();
});
System.out.println("*** main end ***");
}
Tout d'abord, le traitement de l'argument de Completable.create (dans le lambda) est exécuté. Le traitement lui-même est le même que le traitement de Main.java au début.
Ensuite, emitter.onComplete () En appelant, le premier argument de subscribe est exécuté.
Au fait, le deuxième argument de subscribe est lorsque vous appelez emitter.onError () Sinon, il sera exécuté lorsqu'une erreur est renvoyée dans le lambda de l'argument de Completable.create. Le jetable qui y est passé sera l'objet d'erreur qui s'est produit en cas d'erreur.
Résumé, Traitement des arguments Completable.create → Souscrire le traitement du 1er argument (onSuccess) ou le traitement du 2ème argument (onError) Le processus est exécuté dans le flux.
SingleSample.java
public static void main(String[] args) {
System.out.println("*** main start ***");
Single.<List<RestUtil.Weather>>create(emitter -> {
RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
emitter.onSuccess(List.of(tokyoWeather, yokohamaWeather, nagoyaWeather));
}).subscribe(weathers -> {
System.out.println("Complete!!");
for (RestUtil.Weather weather : weathers) {
System.out.println(weather);
}
}, throwable -> {
System.out.println("Error!!");
throwable.printStackTrace();
});
System.out.println("*** main end ***");
}
Comme le Completable de la partie 1 Gestion des arguments Single.create → Souscrire le traitement du 1er argument (onSuccess) ou le traitement du 2ème argument (onError) Le processus est exécuté dans le flux.
La différence est l'endroit où la météo est sortie.
Dans Single, vous pouvez transmettre ** une seule ** valeur au traitement suivant, donc Lister la météo dans chaque région emitter.onSuccess(T) En appelant, il est passé au traitement du premier argument de subscribe. De plus, le type de l'argument qui y est passé est spécifié par les génériques au moment de Single # create.
Si vous avez traité Promise en JavaScript, l'image est similaire.
StreamSample.java
/**
* sample for Stream
*/
public static void main(String[] args) {
System.out.println("*** main start ***");
RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
Stream.of(List.of(tokyoWeather, yokohamaWeather, nagoyaWeather))
.forEach(weather -> {
System.out.println(weather + "");
});
System.out.println("*** main end ***");
}
Avant de parler d'Observable, apprenons un peu plus sur Stream. Si vous comprenez déjà Stream, ignorez-le.
Ensuite, le flux de traitement, Tout d'abord, obtenez la météo de chaque district et générez une liste, Il est diffusé et la météo de chaque district est sortie.
La forme sous laquelle les valeurs circulent en séquence est similaire à Observable, qui sera expliquée ci-après. Veuillez comprendre le déroulement du processus.
ObservableSample.java
public static void main(String[] args) {
System.out.println("*** main start ***");
Observable.<RestUtil.Weather>create(emitter -> {
RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
emitter.onNext(tokyoWeather);
RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
emitter.onNext(yokohamaWeather);
RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
emitter.onNext(nagoyaWeather);
emitter.onComplete();
}).subscribe(weather -> {
System.out.println("Next!!");
System.out.println(weather);
}, throwable -> {
System.out.println("Error!!");
throwable.printStackTrace();
}, () -> {
System.out.println("Complete!!");
});
System.out.println("*** main end ***");
}
Contrairement à Completable et Single conventionnel, Il y a trois arguments pour s'abonner.
En tant que flux de traitement Le processus Observable.create est exécuté en premier. Après cela, le premier argument de subscribe est exécuté à chaque fois que emitter.onNext (T) est appelé. Enfin, lorsque emitter.onComplete () est appelé, le troisième argument de subscribe est exécuté. Le deuxième argument est le processus qui est appelé lorsqu'une erreur se produit, comme par le passé.
Résumé, Traitement Observable.create → Souscrire le traitement du 1er argument (onNext) ou du 2ème argument (onError) → Traitement du troisième argument (onComplete) de souscription Le processus est exécuté dans le flux.
Observable peut transmettre plusieurs valeurs, de sorte qu'il peut générer la valeur à chaque fois qu'une communication est effectuée.
ThreadSample.java
public static void main(String[] args) {
System.out.println("*** main start ***");
Observable.<RestUtil.Weather>create(emitter -> {
RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
emitter.onNext(tokyoWeather);
RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
emitter.onNext(yokohamaWeather);
RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
emitter.onNext(nagoyaWeather);
emitter.onComplete();
}).subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.subscribe(weather -> {
System.out.println("Next!!");
System.out.println(weather);
}, throwable -> {
System.out.println("Error!!");
throwable.printStackTrace();
}, () -> {
System.out.println("Complete!!");
});
System.out.println("*** main end ***");
}
Dans le code source expliqué dans la partie 4 "subscribeOn", "observeOn" A été ajouté.
Il y a quelques avantages de RxJava, Le plus important est que le processus de spécification de ce fil est facile à écrire.
"subscribeOn" spécifie le thread de traitement dans Observable.create, "observeOn" peut spécifier le thread de traitement dans subscribe.
Dans l'exemple ci-dessus, le traitement de la communication est effectué par le thread IO. Le traitement suivant (traitement qui utilise le résultat de la communication) est exécuté par un autre thread.
En tant que scène souvent utilisée, dans le développement Android, le traitement de la communication est effectué dans un thread séparé, Il est courant que le thread principal effectue le traitement qui gère la vue dans le traitement suivant.
ObservableMapSample.java
public static void main(String[] args) {
System.out.println("*** main start ***");
Observable.<RestUtil.Weather>create(emitter -> {
RestUtil.Weather tokyoWeather = RestUtil.getWeather(RestUtil.Place.TOKYO);
emitter.onNext(tokyoWeather);
RestUtil.Weather yokohamaWeather = RestUtil.getWeather(RestUtil.Place.YOKOHAMA);
emitter.onNext(yokohamaWeather);
RestUtil.Weather nagoyaWeather = RestUtil.getWeather(RestUtil.Place.NAGOYA);
emitter.onNext(nagoyaWeather);
emitter.onComplete();
}).map(weather -> {
switch (weather) {
case SUNNY:
return "happy day!!";
case RAINY:
return "sad day...";
case WINDY:
default:
return "normal day";
}
}).subscribe(weather -> {
System.out.println("Next!!");
System.out.println(weather);
}, throwable -> {
System.out.println("Error!!");
throwable.printStackTrace();
}, () -> {
System.out.println("Complete!!");
});
System.out.println("*** main end ***");
}
Une nouvelle carte de méthode a été ajoutée au code source de la partie 4. Vous pouvez voir que vous pouvez réellement le déplacer, La valeur passée au premier argument de subscribe a été ** convertie **.
Comme vous pouvez le voir, ce qui est converti est le processus passé à la carte.
La carte reçoit la valeur qui coule et renvoie la valeur convertie dans la clause de retour. Vous pouvez convertir la valeur à envoyer au traitement suivant.
ObservableFlatMapSample.java
public static void main(String[] args) {
System.out.println("*** main start ***");
Observable.<RestUtil.Place>create(emitter -> {
emitter.onNext(RestUtil.Place.TOKYO);
emitter.onNext(RestUtil.Place.YOKOHAMA);
emitter.onNext(RestUtil.Place.NAGOYA);
emitter.onComplete();
}).flatMap(place -> {
return Observable.create(emitter -> {
RestUtil.Weather tokyoWeather = RestUtil.getWeather(place);
emitter.onNext(tokyoWeather);
emitter.onComplete();
});
}).subscribe(weather -> {
System.out.println("Next!!");
System.out.println(weather);
}, throwable -> {
System.out.println("Error!!");
throwable.printStackTrace();
}, () -> {
System.out.println("Complete!!");
});
System.out.println("*** main end ***");
}
Une nouvelle méthode flatMap a été ajoutée au code source de la partie 4. La valeur transmise dans le premier Observable.create a changé de météo en région. Et un autre Observable est généré dans flatMap.
Le flux de traitement est Le premier processus Observable est exécuté, Chaque fois que emitter.onNext (T) est appelé Le traitement dans le deuxième Observable qui est retourné dans le flatMap est effectué. En d'autres termes, flatMap relie le premier Observable et le second Observable.
Dans cet exemple, le point de communication n'est que le deuxième observable, il n'y a donc pas de goût particulier, mais En fait, le traitement DB est effectué avec le premier Observable, Le traitement de la communication est effectué avec le deuxième Observable Il est utilisé dans les scènes où un traitement long et long est effectué.
Avec ce qui précède, "Lisez! RxJava »est terminé.
Parce que le monde de RxJava est vaste et toujours en croissance Le contenu de cet article ne suffit pas à tout couvrir, Vous devriez être capable de comprendre les bases en combinant et en appliquant les classes et les méthodes présentées ici. (Au moins dans le sens d'être lisible)
J'espère pouvoir aider tous ceux qui vont se lancer dans le monde de RxJava.
Recommended Posts