2017-05-08 35 views
1

我是RxJava的新手。我想從JSON API中獲取數據。假設有兩個API API 1和API 2.我們從API 1中獲取一個JSON對象「mediaId」。現在,我想用「mediaId」從API 2獲取JSON。我如何使用RxJava實現這一點,並在Android中進行改進?如何使用帶有改型的RxJava從多個API獲取數據2

public void gettdata(final Listerner listerner){ 

    postitemses= new ArrayList<>(); 
    Retrofit retrofit = new Retrofit.Builder() 
      .baseUrl("https://www.mytrendin.com") 
      .addConverterFactory(GsonConverterFactory.create()) 
      .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
      .build(); 

    APiService networkAPI = retrofit.create(APiService.class); 

    Observable<List<Postitems>> observable = networkAPI.getFriendObservable() 
            .subscribeOn(Schedulers.newThread()) 
            .observeOn(AndroidSchedulers.mainThread()); 

    observable.subscribe(new Observer<List<Postitems>>() { 
     @Override 
     public void onCompleted() { 

     } 

     @Override 
     public void onError(Throwable e) { 

      listerner.onFailure("oops... Something went wrong"); 
     } 

     @Override 
     public void onNext(List<Postitems> postitemsList1) { 

      Postitems postitems; 
      for (int i=0;i<postitemsList1.size();i++){ 
       postitems = new Postitems(); 
       int id = postitemsList1.get(i).getId(); 
       String title = postitemsList1.get(i).getTitle().getRendered(); 
       String shortdesc= postitemsList1.get(i).getExcerpt().getRendered(); 
       String mediaid= postitemsList1.get(i).getFeatured_media(); 
       String authorid= postitemsList1.get(i).getAuthor(); 
       String date = postitemsList1.get(i).getDate(); 
       String slug = postitemsList1.get(i).getSlug(); 
       Log.i("Hello-slug",""+slug); 
       String[] mediaurl= mydata(mediaid); 
       Log.i("Hello-mediaurl",""+mediaurl); 
       postitems.setId(id); 
       postitems.setDate(date); 
       postitems.setSlug(""+slug); 
       postitems.setPostExcerpt(shortdesc); 
       postitems.setPostTitle(title); 
       postitemses.add(postitems); 

      } 
      listerner.showpostitems(postitemses); 

     } 
    }); 


} 




public String[] mydata(String mediaid){ 


    final String[] mediaurl = new String[1]; 
    Retrofit retrofit = new Retrofit.Builder() 
      .addConverterFactory(GsonConverterFactory.create()) 
      .baseUrl("https://www.mytrendin.com") 
      .build(); 
    APiService aPiService = retrofit.create(APiService.class); 
    Call<Postitems> call = aPiService.getmediaurl(mediaid); 
    call.enqueue(new Callback<Postitems>() { 
     @Override 
     public void onResponse(Call<Postitems> call, Response<Postitems> response) { 

      Postitems postitemsList1 = response.body(); 
      mediaurl[0] =postitemsList1.getGuid().getRendered(); 
      // mediaurl[0][0] =postitemsList1.get(0).getGuid().getRendered(); 
     } 

     @Override 
     public void onFailure(Call<Postitems> call, Throwable t) { 

     } 
    }); 

    return mediaurl; 

}

出錯

https://www.mytrendin.com 3月5日至9日:42:09.227 15315-15315 /? d/AndroidRuntime:關閉VM

          --------- beginning of crash 

3月5日至9日:42:09.228 15315-15315 /? E/AndroidRuntime:致命例外:main 進程:com.mytrendin.mytrendin,PID:15315 java.lang.NullPointerException:試圖調用虛方法.mytrendin.dashboard.utils.Po stitems $ Guid(ZygoteInit.java:755)

+0

你是否做了什麼了嗎?發佈您的代碼,以便我們可以幫助您完成您的工作 –

+0

嘗試檢查https://github.com/eurosecom/Attendance/blob/master/app/src/main/java/com/eusecom/attendance/fragments/RetrofitFragment方法onListContributorsWithFullUserInfoClicked()中的.java我調用由Rx zip運算符ziped的2個retrofitservices。 – eurosecom

+0

觀看https://github.com/kaushikgopal/RxJava-Android-Samples/blob/master/README.md#4-networking-with-retrofit--rxjava-using-zip-flatmap – eurosecom

回答

0

當然你可以使用該合併操作與IO scheduler.By定義一起,合併可以合併他們emissions.here就是一個例子多觀測量合併成一個,

Observable<Integer> odds = Observable.just(1, 3, 5).subscribeOn(someScheduler); 
Observable<Integer> evens = Observable.just(2, 4, 6); 

Observable.merge(odds, evens) 
      .subscribe(new Subscriber<Integer>() { 
     @Override 
     public void onNext(Integer item) { 
      System.out.println("Next: " + item); 
     } 

     @Override 
     public void onError(Throwable error) { 
      System.err.println("Error: " + error.getMessage()); 
     } 

     @Override 
     public void onCompleted() { 
      System.out.println("Sequence complete."); 
     } 
    }); 

輸出:

下一步:1

下一頁:3

下一頁:5

下一頁:2

下一頁:4

下一頁:6

序列完整。

像這樣的事情在你的情況,

public Observable<Data> getMergedData() { 
    return Observable.merge(
    networkRepository.getData().subscribeOn(Schedulers.io()), 
    networkRepository.getData().subscribeOn(Schedulers.io()) 
); 
} 

好吧,還有另一種方式來解決這個問題,首先要創建一個可觀察到的兩個API,然後訂閱並觀察從你的第一API subscription.Next創建的變化一個PublishSubject實例。這很有用,因爲一旦觀察者已經訂閱,就會將所有隨後觀察到的項目發送給訂閱者。例如,從API響應中發佈字符串值。

private PublishSubject<String> subject = PublishSubject.create(); 


subject.observeOn(AndroidSchedulers.mainThread()).subscribeOn(Schedulers.io()).filter((s) -> s.size() > 0).subscribe(new Observer<String>() { 
      @Override 
      public void onSubscribe(Disposable d) { 

      } 

      @Override 
      public void onNext(String str) { 


      } 

      @Override 
      public void onError(Throwable e) { 

      } 

      @Override 
      public void onComplete() { 

      } 
     }); 

然後觸發來自受試者的觀察到的呼叫onNext。

subject.onNext("some data from api"); 

優點,非常靈活地改變你的班級範圍內的任何地方。

希望這會有所幫助。

爲以下片斷

call.enqueue(new Callback<Postitems>() { 
     @Override 
     public void onResponse(Call<Postitems> call, Response<Postitems> response) { 

      Postitems postitemsList1 = response.body(); 
      mediaurl[0] =postitemsList1.getGuid().getRendered(); 
      // mediaurl[0][0] =postitemsList1.get(0).getGuid().getRendered(); 
//use the concept of publish subject here, which i detailed in answer, example 
subject.onNext(postitemsList1.getGuid().getRendered()); 
//the string data will be passed to the above observable for the subject instance. 
     } 

     @Override 
     public void onFailure(Call<Postitems> call, Throwable t) { 

     } 
    }); 
+0

希望這可以幫助您獲得更多見解! – Remario

+0

我想在evens中使用賠率結果,我該怎麼做。請告訴 –

+0

我有點困惑,你是指執行的並列,因爲上述操作是同步的 – Remario

相關問題