Android: dynamisch passieren Modellklasse, um Rückruf rückgängig zu machen

In der Nachrüstung, um json Antwort auf pojo zu ordnen, tun wir das normalerweise

@POST Call<User> getDataFromServer(@Url String url, @Body HashMap<String,Object> hashMap); ApiCalls api = retrofit.create(ApiCalls.class); Call<User> call = api.getDataFromServer(StringConstants.URL,hashMap); call.enqueue(new Callback<User>() { //Response and failure callbacks } 

Wo Benutzer meine Pojo-Klasse ist. Aber für jede andere Anfrage muss ich verschiedene pojo und schreiben gleichen Code für Retrofit Call.Ich möchte eine einzige Methode für den Aufruf von api und übergeben die jeweilige Pojo-Klasse nachrüsten rufen. so was

  • Löschen von androiden sqllite Zeilen älter als x Tage
  • Wie bekomme ich eine ClickableSpan in einem TextView?
  • Benutzerdefinierte byteArray Daten zu WebRTC videoTrack
  • Gradle Javadoc Aufgabe ohne Warnungen
  • Android: listview item width fill_parent funktioniert nicht
  • Verwenden von Android Intent.ACTION_SEND zum Senden von E-Mails
  •  ApiCalls api = retrofit.create(ApiCalls.class); Call<*ClassPassed*> call = api.getDataFromServer(StringConstants.URL,hashMap); call.enqueue(new Callback<*ClassPassed*>() { //Response and failure callbacks } 

    So jetzt kann ich jede pojo klasse zu einer einzigen methode und bekomme die response.This ist nur zu vermeiden, umschreiben den gleichen Code wieder und wieder. Ist dies möglich

    Update Um mehr zu erarbeiten:

    Angenommen, ich brauche zwei Anfragen. Erster ist es, UserDetails zu bekommen und der andere ist patientDetails.So muss ich zwei Modellklassen User und Patient erstellen. Also in der Nachrüstung api Ich werde so etwas haben

     @POST Call<User> getDataFromServer(@Url String url, @Body HashMap<String,Object> hashMap); @POST Call<Patient> getDataFromServer(@Url String url, @Body HashMap<String,Object> hashMap); 

    Und in meiner FragmentUser- und FragmentPatient-Klasse werde ich das machen

      ApiCalls api = retrofit.create(ApiCalls.class); Call<User> call = api.getDataFromServer(StringConstants.URL,hashMap); call.enqueue(new Callback<User>() { //Response and failure callbacks } ApiCalls api = retrofit.create(ApiCalls.class); Call<Patient> call = api.getDataFromServer(StringConstants.URL,hashMap); call.enqueue(new Callback<Patient>() { //Response and failure callbacks } 

    Aber hier ist der Code repariert nur Beacuse von verschiedenen pojo Klassen.Ich muss den gleichen Code in jedem anderen Fragmente für verschiedene Anfragen wiederholen. Also muss ich eine generische Methode machen, wo es irgendeine Pojo-Klasse akzeptieren kann und dann aus Fragment werde ich nur das Pojo passieren, um abgebildet zu werden.

  • Gestenerkennung In Android
  • Wie konfiguriere ich VPN programmgesteuert?
  • Wie richtig eingestellt Höhenwert zu recyclerview?
  • Wie kann ich den Namen des Android-App-Pakets beim Zusammenbau mit Gradle ändern?
  • Rekursiver Eintrag zum AusführenPendingTransactions
  • Konnte nicht finden com.android.support:appcompat-v7:25.3.1
  • 8 Solutions collect form web for “Android: dynamisch passieren Modellklasse, um Rückruf rückgängig zu machen”

    Du kannst das Hauptpfoten so bauen

     public class BaseResponse<T> { @SerializedName("Ack") @Expose private String ack; @SerializedName("Message") @Expose private String message; @SerializedName("Data") @Expose private T data; /** * * @return * The ack */ public String getAck() { return ack; } /** * * @param ack * The Ack */ public void setAck(String ack) { this.ack = ack; } /** * * @return * The message */ public String getMessage() { return message; } /** * * @param message * The Message */ public void setMessage(String message) { this.message = message; } /** * * @return * The data */ public T getData() { return data; } /** * * @param data * The Data */ public void setData(T data) { this.data = data; } } 

    Und rufe so an

      Call<BaseResponse<SetupDetails>> getSetup(@Query("site_id") int id,@Query("ino") String ii); 

    Erste Schnittstelle erstellen:

     public interface ItemAPI { @GET("setup.php") Call<SetupDetails> getSetup(@Query("site_id") int id,@Query("ino") String ii); @GET("setup.php") void setMy(@Query("site_id") int id, Callback<List<SetupDetails>> sd); } 

    Jetzt schaffen Klasse:

     public class Apiclient { private static final String BASE_URL ="http://www.YOURURL.COM/"; private static Retrofit retrofit = null; public static Retrofit getClient() { OkHttpClient.Builder httpClient2 = new OkHttpClient.Builder(); httpClient2.addNetworkInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request.Builder builder = chain.request().newBuilder(); builder.addHeader("site_id","1"); return chain.proceed(builder.build()); } }); OkHttpClient client = httpClient2.build(); if (retrofit == null) { retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(client) .addConverterFactory(GsonConverterFactory.create()) .build(); } return retrofit; } 

    Jetzt in jeder Aktivität nur verwenden:

     ItemAPI itemAPI = Apiclient.getClient().create(ItemAPI.class); Call<AllProducts> call=itemAPI.getSetup(1,count); call.enqueue(new Callback<AllProducts>() { @Override public void onResponse(Call<AllProducts> call, Response<AllProducts> response) { try { if (response.body().getItem().size()>0){ } }catch (Exception e){ e.printStackTrace(); } } @Override public void onFailedAfterRetry(Throwable t) { } }); 

    Mein Ansatz ist ein POJO namens ResponseData, in dem Sie ein Attribut Objekt haben, so haben Sie:

     @POST Call<ResponseData> getDataFromServer(@Url String url, @Body HashMap<String,Object> hashMap); 

    Wenn du die Antwort bekommst, musst du dein response.body () auf die gewünschte Klasse punkten. Also die Profis: Du hast nur eine Bitte, stattdessen musst du die Antwort analysieren.

    Mach es so :

      @POST Call<Object> getDataFromServer(@Url String url, @Body HashMap<String,Object> hashMap); ApiCalls api = retrofit.create(ApiCalls.class); Call<Object> call = api.getDataFromServer(StringConstants.URL,hashMap); call.enqueue(new Callback<User>() { @Override public void onResponse(Call<Object> call, Response<Object> response) { YourModel modelObject = (YourModel) response.body(); } @Override public void onFailure(Call<Object> call, Throwable t) { } } 

    Um zu verallgemeinern, was du willst, kannst du einfach deinen POJO serialisieren, und dann kannst du einfach deinen POJO an die Methode weitergeben, wie es ist. Wenn du mit Objekten serialisierst, konvertiert sie es grundsätzlich in String, die später in eine große Json String umgewandelt werden, die einfacher zu übertragen und zu manipulieren sind.

    Ein kurzes Beispiel wäre:

    Beispiel POJO Implementierung der Serialisierung, hier sollten Sie sicherstellen, dass die Strings in der Map<String,Object> entsprechen, was der Server erwartet, und diese Methode sollte in jedem POJO unterschiedlich sein:

     public class YourPojo implements ObjectSerializer { private static final long serialVersionUID = -1481977114734318563L; private String itemName; private int itemId; @Override public Map<String, Object> objectSerialize() { Map<String, Object> map = new HashMap<>(); map.put("itemid", itemId); // server will be looking for "itemid" map.put("itemname", itemName); // server will be looking for "itemname" } //other stuff you need.... } 

    Die Serialisierungsschnittstelle (so können Sie sie über andere POJOs implementieren)

     public interface ObjectSerializer extends Serializable { public Map<String, Object> objectSerialize(); } 

    Und ein Json-Parser, den du schulst, hast wohl sowieso:

     public class JsonParser { public static JSONObject serializeToJsonString(Map<String, Object> jsonParams) { Gson gson = new Gson(); String json = gson.toJson(jsonParams); JSONObject object; try { object = new JSONObject(json); } catch (Exception e) { object = new JSONObject(jsonParams); } return (object); } } 

    Und zuletzt, deine API-Definition:

     @POST("users/createitem") Call<ResponseBody> someCall(@Body RequestBody params); 

    Und Methode, die in einer allgemeinen Klasse sitzen sollte, die deine Anfragen verwaltet:

     public void someMethodName(YourPojo item, final CustomEventListener<String> listener) { JSONObject object = JsonParser.serializeToJsonString(item.objectSerialize()); RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8";), object.toString()); Call<ResponseBody> requestCall = serviceCaller.someCall(body); requestCall.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> rawResponse) { try { String response = rawResponse.body().string(); //do what you want with this string listener.getResult(response); } catch (Exception e) { e.printStackTrace(); } } @Override public void onFailure(Call<ResponseBody> call, Throwable throwable) { } }); } 

    Ich gebe die Antwort durch einen Zuhörer zurück, das ist ein Beispiel dafür, was du je nach deiner Antwort tun kannst.

    Hoffe das hilft!

    Sie müssen Generika verwenden. Auf diese Weise können Sie den gewünschten Typ in den Anruf übergeben.

     @POST Call<T> getDataFromServer(@Url String url, @Body HashMap<String,Object> hashMap, Class<T> requestClass); ApiCalls api = retrofit.create(ApiCalls.class); Call<T> call = api.getDataFromServer(StringConstants.URL,hashMap); call.enqueue(new Callback<T>() { //Response and failure callbacks } 

    Übrigens bin ich kein Retrofit-Experte (ich verwende meine Sachen meistens), aber ich denke, du benutzt es falsch.

    Es gibt 2 Möglichkeiten, dies zu tun ………

    1. Generika

    2. Kombiniere alle POJO zu einem ……

    Generika

    In den Generika müssen Sie die Methode mit der Klasse übergeben. Pleas schauen auf beispiel …..

     ApiCalls api = retrofit.create(ApiCalls.class); Call<User> call = api.getDataFromServer(StringConstants.URL,hashMap); callRetrofit(call,1); public static <T> void callRetrofit(Call<T> call,final int i) { call.enqueue(new Callback<T>() { @Override public void onResponse(Call<T> call, Response<T> response) { if(i==1){ User user = (User) response.body(); // use the user object for the other fields }else if (i==2){ Patient user = (Patient) response.body(); } } @Override public void onFailure(Call<T> call, Throwable t) { } }); } 

    HINWEIS: – Oberhalb der Nachrüstung rufen Sie TypeCast Ihre Antwort in YOUR OBJECT , so können Sie auf sein Feld und Methoden zugreifen

    Kombiniere alle POJO zu einem

    Es ist sehr einfach zu bedienen. Du musst deine alle POJO Klasse zu einem kombinieren und sie in der Retrofit verwenden. Bitte schau nach unten

    Ich habe zwei API Login und Benutzer ……

    In Anmelde-API habe ich JSON Antwort wie folgt bekommen …

    {"Success": True, "message": "Authentication erfolgreich"}

    Über JSON, POJO sieht so aus

     public class LoginResult{ private String message; private boolean success; //constructor , getter and setter } 

    Und Retrofit Call sieht so aus …..

      call.enqueue(new Callback<LoginResult>() { @Override public void onResponse(Call<LoginResult> call, Response<LoginResult> response) { } @Override public void onFailure(Call<LoginResult> call, Throwable t) { } }); 

    In User API habe ich JSON Antwort wie folgt bekommen …

    {"Name": "sushildlh", "place": "hyderabad"}

    Über JSON, POJO sieht so aus

      public class UserResult{ private String name; private String place; //constructor , getter and setter } 

    Und Retrofit Call sieht so aus …..

      call.enqueue(new Callback<UserResult>() { @Override public void onResponse(Call<UserResult> call, Response<UserResult> response) { } @Override public void onFailure(Call<UserResult> call, Throwable t) { } }); 

    Kombiniere einfach beide JSON-Antwort zu einem …..

     public class Result{ private String name; private String place; private String message; private boolean success; //constructor , getter and setter } 

    Und verwenden Sie Ergebnis in Ihrem API-Aufruf ……

      call.enqueue(new Callback<Result>() { @Override public void onResponse(Call<Result> call, Response<Result> response) { } @Override public void onFailure(Call<Result> call, Throwable t) { } }); 

    Hinweis: – Sie kombinieren direkt Ihre 2 POJO Klasse und greifen darauf zu. (Dies ist sehr kompliziert, wenn Sie Antwort sehr groß und bieten Duplikation, wenn einige KEY ist gleich mit verschiedenen Variable Typ)

    Verwenden Sie Standard-Generika, mit ein wenig Hacken um

    Definiere deine Schnittstelle so

     public interface ApiCalls<T> { @POST Call<T> getResult getDataFromServer(@Url String url, @Body HashMap<String,Object> hashMap); } 

    Und rufen für die Erstellung von api-Client verwenden eine Helfer-Methode

     class HelperMethods { @SuppressWarnings("unchecked") private static <T> ApiCalls<T> getClient() { return retrofit.create((Class<ApiCalls<T>>)(Class<?>)ApiCalls.class); } } ApiCalls<User> api = HelperMethods.getClient(); 

    Aber trotz der Tatsache, wie oft es hier gesagt wurde, werde ich es noch einmal sagen … Tu das nicht … Du gibst die ganze Art Sicherheit und Vertragsvalidierung auf, die Retrofit anbietet. Das ist eigentlich Die aufregendste Sache darüber ..

    Das Android ist ein Google Android Fan-Website, Alles ├╝ber Android Phones, Android Wear, Android Dev und Android Spiele Apps und so weiter.