2016-01-27 3 views
7

Ich bin neu in Android und Retrofit und ich stehe vor einem Problem.So trennen Sie Anwendungslogik von Netzwerkebene in Android mit Retrofit 2

Ich möchte meine sagen "ServerCommunication" -Klasse (singelton), wo alle Retrofit Magie getan wird, und es wird öffentliche Methoden, wo REST-Aufrufe getan werden.

Ich möchte diese "ServerCommunication" -Instanz in meinen Aktivitäten verwenden, um Rest-Dienst aufzurufen, aber das ist es. Anwendungslogik sollte in Aktivität durchgeführt werden. Auf diese Art und Weise ruft die Login-Methode die Methode Login (POJORequest) in "ServerCommunication" auf, wo der eigentliche REST-Aufruf über das Retrofit-Framework erfolgt und POJOResponse zurückgegeben wird. Somit kümmert sich Activity nicht um die REST-Kommunikation, während ServerCommunication sich nicht darum kümmert sollte auf die Antwort vom REST-Dienst seit

angewendet werden

Mit Nachrüstung 2 Ich verstehe nicht, wie ich Aktivität blockieren kann, um auf die Antwort von Retrofit zu warten und wie es zurückgegeben werden kann. Nun, ich könnte denken, dass ich einige Rückrufmethoden verwenden kann In Aktivität können diese Methoden von ServerCommunication "in OnPostExecute() aufgerufen werden, um eine gewisse Logik basierend auf Daten aus der Antwort anzuwenden. Ich denke es sollte einfacher sein.

Nun, um alle diese Unordnung oben zu verdeutlichen, stellen Sie sich einen einfachen Fall vor: Sie haben Daten in Ihrer Haupttätigkeit, übergeben Sie diese Daten an Ihre Kommunikationsklasse, wo REST-Aufruf erfolgt und Antwort empfangen wird. Diese Antwort muss validiert werden, um fortfahren zu können. Und Sie möchten, dass diese Validierung in der Hauptaktivität und NICHT in der Kommunikationsklasse erfolgt.

Was ist Pattern, das in Android mit Retrofit2 zu tun?

Vielen Dank im Voraus

Antwort

6

Was ich normalerweise tun:

  • Erstellen Sie Ihr Interface (wo Sie alle Ihre REST-Methoden haben - GET & POST usw.)
  • Erstellen Sie eine Klasse, die die tatsächliche tut Aufrufe mit entsprechenden Methoden (siehe Interface REST-Methoden). Ich würde es so etwas wie ServiceAPIImplementor nennen. Hier erstellen Sie Ihren Retrofit-Adapter.
  • Erstellen Sie in Ihrer Aktivität eine Instanz Ihrer Implementierungsklasse, rufen Sie die Methoden auf und übergeben Sie die erwarteten Argumente.
  • Nachdem Sie die Methoden aufgerufen haben, sollten Sie wahrscheinlich einen Fortschrittsdialog anzeigen, damit der Benutzer weiß, dass etwas passiert.
  • Wenn die onResponse oder onFailure Methode aufgerufen wird, wird ein Ereignismuster verwenden (EventBus Bibliothek?) Um die Aktivität zu benachrichtigen, dass die Netzwerkoperation abgeschlossen ist. Sobald die Aktivität die Benachrichtigung erhalten hat, sollte sie den Fortschrittsdialog schließen und die Benutzeroberfläche entsprechend aktualisieren - mit den neu empfangenen Daten oder der abgeschlossenen Operation (erwartetes Ergebnis).

Ich hoffe, dass dies hilft Ihnen näher zu kommen, was Sie erreichen wollen!

+0

Danke für deine Antwort. Nun, EventBus hat es geschafft, aber ich habe immer noch das Gefühl, dass es eher eine Umgehungslösung ist. Ich muss noch onEventMainThread() zu Aktivität hinzufügen, wo ich Antwort von ServiceAPIImplementor (oder was auch immer wir es) erhalten und UI ist eigentlich nicht blockiert, obwohl wir es hinter einigen Fortschrittsdialog verstecken oder einfach nur Kontrollen deaktivieren. Ich möchte vermeiden, zusätzliches Ereignis Muster-Framework hinzufügen, wenn alles, was ich tun möchte, ist Methode SomeResponse callRestService (SomeRequest Req) in ServiceAPIImplementor – Tony

+0

und einfach Instanz davon in Aktivität haben und etwas wie SomeResponse resp = serv.callRestService (Req) tun ; Retrofit 2 bietet die Möglichkeit, die Verbindung und andere Zeitüberschreitungen zu konfigurieren, sodass das Blockieren der Benutzeroberfläche nicht zum Problem wird. Ich denke also, die beste Lösung wäre, wenn ich wählen kann, wann ich REST-Aufrufe vom UI-Thread und wann vom Hintergrund aus tun möchte. – Tony

+0

Aber wenn es nicht möglich ist, würde ich bei EventBus Lösung bleiben, aber ich habe eine Frage. Gibt es irgendwelche Vorteile mit EventsBus über die Lösung, wenn ich einfach Callback-Methode in Aktivität implementieren und es von OnResponse oder OnFailure-Methoden in ServiceAPIImplementor aufrufen? – Tony

0

Service-Schnittstelle (IPhotoService):

@GET("/photos/kudos") 
Call<String> fetchKudos(@Header("Authorization") String authorization, 
         @Query("offset") int offset, @Query("mt") boolean mt); 

Service-impl (Photoservice):

private GoApiProvider<IPhotoService> mGoProvider = new GoApiProvider<>(); 

public Promiser<List<Photo>, HttpError> fetchKudos() { 
    return new Promiser<>((resolve, reject) -> 
      mGoProvider.getService(IPhotoService.class).fetchKudos(mSession.getToken(), 
        mOffsetKudos, true).enqueue(new Callback<String>() { 
       @Override 
       public void onResponse(Call<String> call, Response<String> response) { 
        if (response.isSuccessful()) { 
         PhotoParser JSON = new PhotoParser(); 
         try { 
          mOffsetKudos = mOffsetKudos + 20; 
          resolve.run(JSON.photosFromJson(response.body())); 
         } catch (JSONException e) { 
          Log.e("fetchKudos", e.toString()); 
         } 
        } else { 
         reject.run(new HttpError(response.code(), response.message())); 
        } 
       } 

       @Override 
       public void onFailure(Call<String> call, Throwable t) { 
        reject.run(new HttpError(YPErrorType.Undefined.getType(), t.getMessage())); 
       } 
      }) 
    ); 
} 

Aktivität oder Fragment:

private void loadPhoto() { 
    new PhotoService().fetchKudos() 
      .success(this::resultSucceeded) 
      .error(this::resultError); 
} 

private void resultSucceeded(List<Photo> photos) { 
    mPhotoAdapter.setItems(photos); 
} 

private void resultError(HttpError httpError) { 
    httpErrorToast(httpError); 
} 

Wenn Sie Promizer verwenden: Click here

Verwandte Themen