Android
Eftermontering med RxJava
Sök…
Eftermontering med RxJava
Lägg först relevanta beroenden i build.gradle-filen.
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'
....
}
Skapa sedan den modell du vill ha:
public class Server {
public String name;
public String url;
public String apikey;
public List<Site> siteList;
}
Skapa ett gränssnitt som innehåller metoder som används för att utbyta data med fjärrservern:
public interface ApiServerRequests {
@GET("api/get-servers")
public Observable<List<Server>> getServers();
}
Skapa sedan en Retrofit
instans:
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;
}
Ring sedan metoden var som helst från koden:
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
}
});
Eftermontera med RxJava för att hämta data asynkront
Från GitHub-repo från RxJava är RxJava en Java VM-implementering av Reactive Extensions: ett bibliotek för att komponera asynkrona och händelsebaserade program med användning av observerbara sekvenser. Det utökar observatörsmönstret för att stödja sekvenser av data / händelser och lägger till operatörer som gör att du kan komponera sekvenser tillsammans på ett deklarativt sätt samtidigt som man abstraherar oro över saker som låg nivåtrådning, synkronisering, tråd-säkerhet och samtidiga datastrukturer.
Eftermontering är en typsäker HTTP-klient för Android och Java, med hjälp av detta kan utvecklare göra alla nätverkssaker mycket enklare. Som ett exempel kommer vi att ladda ner lite JSON och visa det i RecyclerView som en lista.
Komma igång:
Lägg till RxJava-, RxAndroid- och eftermonteringsberoenden i din appnivå build.gradle-fil: 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"
Definiera ApiClient och ApiInterface för att utbyta data från servern
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;
}}
offentligt gränssnitt ApiInterface {
@GET("repos/{org}/{repo}/issues")
Observable<List<Issue>> getIssues(@Path("org") String organisation,
@Path("repo") String repositoryName,
@Query("page") int pageNumber);}
Observera att getRepos () returnerar en observerbar och inte bara en lista med problem.
Definiera modellerna
Ett exempel på detta visas. Du kan använda gratis tjänster som JsonSchema2Pojo eller detta.
public class Comment {
@SerializedName("url")
@Expose
private String url;
@SerializedName("html_url")
@Expose
private String htmlUrl;
//Getters and Setters
}
Skapa eftermonteringsinstans
ApiInterface apiService = ApiClient.getInstance().create(ApiInterface.class);
Använd sedan den här instansen för att hämta data från servern
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));
}
});
Nu har du framgångsrikt hämtat data från en server med Retrofit och RxJava.
Exempel på kapslade förfrågningar: flera förfrågningar, kombinera resultat
Anta att vi har ett API som tillåter oss att få objektmetadata i enskild begäran ( getAllPets
) och annan begäran som har fullständig data för en enda resurs ( getSinglePet
). Hur kan vi fråga dem alla i en enda kedja?
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;
}
}
}