Android
Retrofit2 avec RxJava
Recherche…
Retrofit2 avec RxJava
Tout d'abord, ajoutez les dépendances pertinentes dans le fichier build.gradle.
dependencies {
....
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
....
}
Créez ensuite le modèle que vous souhaitez recevoir:
public class Server {
public String name;
public String url;
public String apikey;
public List<Site> siteList;
}
Créez une interface contenant les méthodes utilisées pour échanger des données avec le serveur distant:
public interface ApiServerRequests {
@GET("api/get-servers")
public Observable<List<Server>> getServers();
}
Ensuite, créez une instance Retrofit
:
public ApiRequests DeviceAPIHelper ()
{
Gson gson = new GsonBuilder().create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://example.com/")
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
api = retrofit.create(ApiServerRequests.class);
return api;
}
Ensuite, n'importe où depuis le code, appelez la méthode:
apiRequests.getServers()
.subscribeOn(Schedulers.io()) // the observable is emitted on io thread
.observerOn(AndroidSchedulers.mainThread()) // Methods needed to handle request in background thread
.subscribe(new Subscriber<List<Server>>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<Server> servers) {
//A list of servers is fetched successfully
}
});
Mise à niveau avec RxJava pour récupérer les données de manière asynchrone
À partir du dépôt GitHub de RxJava, RxJava est une implémentation Java de Reactive Extensions: une bibliothèque pour composer des programmes asynchrones et basés sur des événements en utilisant des séquences observables. Il étend le motif de l'observateur pour prendre en charge des séquences de données / événements et ajoute des opérateurs qui vous permettent de composer des séquences de manière déclarative tout en évitant les problèmes tels que le threading de bas niveau, la synchronisation, la sécurité des threads et les structures de données simultanées.
Retrofit est un client HTTP de type sécurisé pour Android et Java. Grâce à cela, les développeurs peuvent simplifier tous les aspects du réseau. Par exemple, nous allons télécharger des fichiers JSON et les afficher dans RecyclerView sous forme de liste.
Commencer:
Ajoutez les dépendances RxJava, RxAndroid et Retrofit dans votre fichier build.gradle au niveau de l'application: compile "io.reactivex:rxjava:1.1.6"
compile "io.reactivex:rxandroid:1.2.1"
compile "com.squareup.retrofit2:adapter-rxjava:2.0.2"
compile "com.google.code.gson:gson:2.6.2"
compile "com.squareup.retrofit2:retrofit:2.0.2"
compile "com.squareup.retrofit2:converter-gson:2.0.2"
Définir ApiClient et ApiInterface pour échanger des données du serveur
public class ApiClient {
private static Retrofit retrofitInstance = null;
private static final String BASE_URL = "https://api.github.com/";
public static Retrofit getInstance() {
if (retrofitInstance == null) {
retrofitInstance = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofitInstance;
}
public static <T> T createRetrofitService(final Class<T> clazz, final String endPoint) {
final Retrofit restAdapter = new Retrofit.Builder()
.baseUrl(endPoint)
.build();
return restAdapter.create(clazz);
}
public static String getBaseUrl() {
return BASE_URL;
}}
interface publique ApiInterface {
@GET("repos/{org}/{repo}/issues")
Observable<List<Issue>> getIssues(@Path("org") String organisation,
@Path("repo") String repositoryName,
@Query("page") int pageNumber);}
Notez que getRepos () renvoie un objet Observable et pas seulement une liste de problèmes.
Définir les modèles
Un exemple pour cela est montré. Vous pouvez utiliser des services gratuits comme JsonSchema2Pojo ou ceci.
public class Comment {
@SerializedName("url")
@Expose
private String url;
@SerializedName("html_url")
@Expose
private String htmlUrl;
//Getters and Setters
}
Créer une instance de modification
ApiInterface apiService = ApiClient.getInstance().create(ApiInterface.class);
Ensuite, utilisez cette instance pour extraire des données du serveur
Observable<List<Issue>> issueObservable = apiService.getIssues(org, repo, pageNumber);
issueObservable.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.map(issues -> issues) //get issues and map to issues list
.subscribe(new Subscriber<List<Issue>>() {
@Override
public void onCompleted() {
Log.i(TAG, "onCompleted: COMPLETED!");
}
@Override
public void onError(Throwable e) {
Log.e(TAG, "onError: ", e);
}
@Override
public void onNext(List<Issue> issues) {
recyclerView.setAdapter(new IssueAdapter(MainActivity.this, issues, apiService));
}
});
Vous avez maintenant récupéré avec succès des données à partir d'un serveur à l'aide de Retrofit et de RxJava.
Exemple de requêtes imbriquées: plusieurs demandes, combiner les résultats
Supposons que nous ayons une API qui nous permette d'obtenir des métadonnées d'objet dans une requête unique ( getAllPets
), et une autre requête qui possède des données complètes de ressource unique ( getSinglePet
). Comment pouvons-nous tous les interroger dans une seule chaîne?
public class PetsFetcher {
static class PetRepository {
List<Integer> ids;
}
static class Pet {
int id;
String name;
int weight;
int height;
}
interface PetApi {
@GET("pets") Observable<PetRepository> getAllPets();
@GET("pet/{id}") Observable<Pet> getSinglePet(@Path("id") int id);
}
PetApi petApi;
Disposable petsDisposable;
public void requestAllPets() {
petApi.getAllPets()
.doOnSubscribe(new Consumer<Disposable>() {
@Override public void accept(Disposable disposable) throws Exception {
petsDisposable = disposable;
}
})
.flatMap(new Function<PetRepository, ObservableSource<Integer>>() {
@Override
public ObservableSource<Integer> apply(PetRepository petRepository) throws Exception {
List<Integer> petIds = petRepository.ids;
return Observable.fromIterable(petIds);
}
})
.flatMap(new Function<Integer, ObservableSource<Pet>>() {
@Override public ObservableSource<Pet> apply(Integer id) throws Exception {
return petApi.getSinglePet(id);
}
})
.toList()
.toObservable()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<Pet>>() {
@Override public void accept(List<Pet> pets) throws Exception {
//use your pets here
}
}, new Consumer<Throwable>() {
@Override public void accept(Throwable throwable) throws Exception {
//show user something goes wrong
}
});
}
void cancelRequests(){
if (petsDisposable!=null){
petsDisposable.dispose();
petsDisposable = null;
}
}
}