2016-07-09 12 views
4

Wie Sie im folgenden Code sehen können, habe ich die getPostByPageId() -Methode aufgerufen, um Daten vom Server zu erhalten und dann zu überprüfen, ob die Daten zurückgegeben wurden, mache ich andere Jobs.Warum rufen Async-Methoden in Retrofit 2 früher auf?

private void recyclerViewJobs() { 
    getPostByPageId(); 
    if (pageDtoList.size() > 0) { 
     emptyText.setVisibility(View.GONE); 
     recyclerView.setVisibility(View.VISIBLE); 
     PagesAdapter adapter = new PagesAdapter(pageDtoList, context); 
     recyclerView.setAdapter(adapter); 
     recyclerView.setLayoutManager(new LinearLayoutManager(context)); 
    } else { 
     emptyText.setVisibility(View.VISIBLE); 
     recyclerView.setVisibility(View.GONE); 
    } 


} 

.....

private void getPostByPageId() { 

    IPageEndPoint pageEndPoint = ServiceGenerator.createService(IPageEndPoint.class); 
    Call<List<PageDto>> call = pageEndPoint.getPostByPageId(profileId); 
    call.enqueue(new retrofit2.Callback<List<PageDto>>() { 
     @Override 
     public void onResponse(Call<List<PageDto>> call, Response<List<PageDto>> response) { 
      if (response.isSuccessful()) { 
       pageDtoList = response.body(); 
      } else { 
       log.toast("response is not successful for getPostByPageId"); 
      } 
     } 

     @Override 
     public void onFailure(Call<List<PageDto>> call, Throwable t) { 
      log.toast("getPostByPageId onFailure"); 
     } 
    }); 
} 

Ich weiß nicht, warum in der recyclerViewJobs() -Methode, um den Zustand, wenn die Arbeit zuerst?

vielleicht könnte ich nicht mein Problem sehr gut erklären, aber mein großes Problem ist zu wissen, wenn ich einige Daten aus REST erhalten mag und diese Daten dann an einen anderen REST-Dienst verwenden, wie kann ich diesen Job tun, weil Enqueue in Retrofit funktioniert asynchron und warten Sie nicht auf die erste Methode, weil davon beginnt die zweite Methode in einem anderen Thread und , weil meine Daten nicht von der ersten Methode noch erhalten wurde, war mein Programm abgestürzt und ich nicht Bekomme die Antwort. Das ist mein Problem .....

Prost

Antwort

1

Ihre async call geführte Aber Ihre if-condition immer falsch weil if-condition geht nicht so verhalten, wie erwartet! Sobald Ihr async request gesendet wird, geht es zu überprüfen if-condition und weil Ihre Liste leer ist (Ihre Antwort vom Server wird noch nicht abgerufen) gibt es immer false.

Wenn Sie nur nächste Operation anrufen möchten, nachdem Ihre WebService Antwort erfolgreich war Sie es mit folgenden Code tun können:

public void onResponse(Call<List<PageDto>> call, Response<List<PageDto>> response) { 
    if (response.body().YOUR_LIST.size() > 0) { 
     emptyText.setVisibility(View.GONE); 
     recyclerView.setVisibility(View.VISIBLE); 
     PagesAdapter adapter = new PagesAdapter(pageDtoList, context); 
     recyclerView.setAdapter(adapter); 
     recyclerView.setLayoutManager(new LinearLayoutManager(context)); 
     //CALL_YOUR_NEXT webservice here 
    } else { 
     emptyText.setVisibility(View.VISIBLE); 
     recyclerView.setVisibility(View.GONE); 
    } 
} 

In Ihrem Process tun Ihren Job. Aber eine Sache, die Sie beachten sollten, ist, dass response.isSuccessful() zurück True die meiste Zeit und es bedeutet nicht, dass Ihre AntwortBody Daten enthält. nach Dokument:

isSuccessful() Gibt true zurück, wenn Code() im Bereich [200..300).

So ist der bessere Weg zu überprüfen, ob Ihre Antwortliste Daten enthält oder nicht.

Aber als eine bessere Möglichkeit (ein bisschen schwierig, wenn Sie Anfänger sind) ist die Verwendung RxJava/RxAndroid. Sie können Ihren Anruf nur nacheinander mit flatMap bearbeiten.

3

Das liegt daran, dass die enqueue Methode von Retrofit keine Blockierungsmethode ist. was bedeutet, dass der Thread, der es aufruft, nicht darauf wartet, dass es seinen Job beendet. Wie @Amir sagte: Wenn Sie andere Dinge nach dem Aufruf von getPostByPageId() zu tun, können Sie sie nach dem Retrofit-Callback setzen sollte:

private void recyclerViewJobs() { 
     getPostByPageId(); 
    } 
    private void getPostByPageId() { 

     IPageEndPoint pageEndPoint = ServiceGenerator.createService(IPageEndPoint.class); 
     Call<List<PageDto>> call = pageEndPoint.getPostByPageId(profileId); 
     call.enqueue(new retrofit2.Callback<List<PageDto>>() { 
      @Override 
      public void onResponse(Call<List<PageDto>> call, Response<List<PageDto>> response) { 
       if (response.isSuccessful()) { 
        pageDtoList = response.body(); 
        if (pageDtoList.size() > 0) { 
         emptyText.setVisibility(View.GONE); 
         recyclerView.setVisibility(View.VISIBLE); 
         PagesAdapter adapter = new PagesAdapter(pageDtoList, context); 
         recyclerView.setAdapter(adapter); 
         recyclerView.setLayoutManager(new LinearLayoutManager(context)); 
        } else { 
         emptyText.setVisibility(View.VISIBLE); 
         recyclerView.setVisibility(View.GONE); 
        } 
       } else { 
        log.toast("response is not successful for getPostByPageId"); 
       } 
      } 

      @Override 
      public void onFailure(Call<List<PageDto>> call, Throwable t) { 
       log.toast("getPostByPageId onFailure"); 
      } 
     }); 
    } 
0

Was ist eine asynchrone Aufgabe?Nicht nur für Retrofit, aber die Antwort ist für alle gleich, wenn Sie asynchrone Aufgabe verwenden, um etwas Code zu schreiben, scheint es, dass Sie diesen Code asynchron laufen lassen, das heißt zu jeder Zeit und auch im Hintergrund, ohne andere zu stören Aufgaben und keine Auswirkungen auf den Haupt-UI-Thread. Eine asynchrone Task definiert sich daher eindeutig als eine Task, die im Hintergrund ausgeführt wird, und der darüber oder darunter geschriebene Code wird davon nicht beeinflusst. In Ihrem Fall ist die asynchrone Aufgabe möglicherweise nicht abgeschlossen oder es ist möglich, dass sie möglicherweise nicht gestartet wurde, aber Ihre if-Bedingung nicht stört. https://developer.android.com/reference/android/os/AsyncTask.html