So verwende ich ein benutzerdefiniertes Google-Such-API, um eine Bild-URL für jeden Namensparameter in meinem Dataset zu erhalten.Iterieren über Netzwerk-API-Aufruf mit Retrofit2
Ich möchte über jeden Namen im Dataset als Abfrageparameter in einem API-Aufruf von Retrofit2 iterieren.
public interface GoogleImageAPI {
@GET("v1?key=MyAPIKEY&cx=MyCustomSearchID&searchType=image&fileType=jpg&imgSize=large&alt=json")
Observable<Photos> loadPhotos(@Query("q") String artistQuery);
}
Bisher habe ich die Retrofit-Adapter und API-Instanz aufgebaut haben einen beobachtbaren zurückzukehren:
public Observable<Photos> getPhotosObservable(String artistName){
Retrofit retrofit = new Retrofit.Builder()
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl("https://www.googleapis.com/customsearch/")
.build();
GoogleImageAPI googleImageAPI = retrofit.create(GoogleImageAPI.class);
return googleImageAPI.loadPhotos(artistName.replace(" ","+"));
}
Ich habe einen getPhotos (String name) -Methode, die eine beobachtbare und abonniert hat es erstellt. Ich bin in der Lage diese Methode mit einem Testparameter zu laufen, iegetPhotos („Rakete“), und es gibt ein Foto Objekt, das eine Liste der Top 10 Google-Foto Suchergebnisse für „rocket“ enthält
public void getPhotos(String artistName){
Observable<Photos> photosObservable = mDataManager.getPhotosObservable(artistName);
Subscription subscription = photosObservable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Photos>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
if(e instanceof HttpException){
HttpException response = (HttpException)e;
Log.i(TAG,"bad response: "+response.code());
}
}
@Override
public void onNext(Photos photos) {
Photos mPhotos = photos;
Log.i(TAG,"size: "+mPhotos);
}
});
}
Gibt es eine sichere/korrekte Art, über diese Methode zu iterieren und folglich die APIs 100 mal aufzurufen, ohne den Speicher zu leeren oder 100 Observable zu erzeugen?
Zum Beispiel könnte ich so etwas tun? Es scheint sehr ressourcenintensiv:
for(String name : artistNames){
googleImageAPI.loadPhotos(name.replace(" ","+"))
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Github>() {
@Override
public final void onCompleted() {
// do nothing
}
@Override
public final void onError(Throwable e) {
Log.e("GithubDemo", e.getMessage());
}
@Override
public final void onNext(Github response) {
mCardAdapter.addData(response);
}
});
}
Edit (Arbeitsbeispiel), die sich in einer kombinierten Liste der Foto-Objekte:
public void getPhotos(){
mDataManager.getArtists()
.subscribeOn(Schedulers.io())
.subscribe(new Action1<JSONArray>() {
@Override
public void call(JSONArray jsonArray) {
LinkedHashMap<Integer,Artist> artistMap = presentArtists(jsonArray);
Collection<Artist> artists = artistMap.values();
Observable.from(artists)
.map(new Func1<Artist, String>() {
@Override
public String call(Artist artist) {
String artistName;
if(artist.getName().contains("(")){
artistName = artist.getName().substring(0,artist.getName().indexOf("(")-2).replace(" ","+");
}else {
artistName = artist.getName().replace(" ", "+");
}
return artistName;
}
})
.flatMap(new Func1<String, Observable<Photos>>() {
@Override
public Observable<Photos> call(String artistName) {
return mDataManager.getPhotosObservable(artistName);
}
})
.toList()
.subscribeOn(Schedulers.io())
.subscribe(new Subscriber<List<Photos>>() {
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<Photos> objects) {
mDataManager.savePhotos(objects);
}
});
}
});
}
Das ist ausgezeichnet, danke. Ich habe eine Arbeitslösung (ohne Lambda) an meine Frage angehängt. Es ist leicht zu sehen, wie Lambda den Code viel sauberer und einfacher zu lesen macht, aber das ist eine Lektion für einen anderen Tag. – Futureproof
@Futureproof mein Vergnügen. Sehen Sie sich auch https://developer.android.com/reference/java/net/URLEncoder.html für URL-Codierungszeichenfolgen an. – LordRaydenMK
Noch besser! Und zu denken, ich hätte fast eine Utility-Klasse erstellt, um alle verschiedenen URL-Variationen zu behandeln. Danke noch einmal. – Futureproof