Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android:dynamically pass model class to retrofit callback

In retrofit to map json response to pojo usually we do this

@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     } 

where User is my Pojo class. But for every other request i need to make different pojo and write same code for retrofit call.I want to make a single method for calling api and pass the respective pojo class to retrofit call. like this

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

so now i can any pojo class to single method and get the response.This is just to avoid rewriting the same code again and again.is this possible

Update To elaborate more:

Suppose I need to make two requests. First one is to get userDetails and the other is patientDetails.So i have to create two model classes User and Patient. So in retrofit api i'll be having something like this

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

and in my FragmentUser and FragmentPatient class i'll be doing this

  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 } 

but here the code is repaeting just beacuse of different pojo classes.I need to repeat the same code in every other fragments for different requests. So i need to make a generic method where it can accept any pojo class and then from fragment i'll be just passing the pojo to be mapped.

like image 249
Rajesh Gosemath Avatar asked Dec 01 '16 05:12

Rajesh Gosemath


People also ask

What is retrofit2?

What is Retrofit. Retrofit is a REST Client for Java and Android allowing to retrieve and upload JSON (or other structured data) via a REST based You can configure which converters are used for the data serialization, example GSON for JSON.

What is retrofit in Android with example?

In Android, Retrofit is a REST Client for Java and Android by Square inc under Apache 2.0 license. Its a simple network library that used for network transactions. By using this library we can seamlessly capture JSON response from web service/web API.


2 Answers

Android:dynamically pass model class to retrofit callback

There is 2 ways you can do this .........

1. Generics

2. Combine all POJO into one ......

Generics

In the Generics you have to pass the method with the class. pleas have look on example .....

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) {              }         });      } 

NOTE:- Above retrofit call TypeCast your response into YOUR OBJECT, so you can access its field and methods

Combine all POJO into one

It is very easy to use . You have to combine your all POJO class into one and use them inside the Retrofit. please have look on below example ....

I have two API login and user......

In Login API i have get JSON response like this ...

{ "success": True, "message": "Authentication successful"}

above JSON , POJO look like this

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

and Retrofit call look like this .....

 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 i have get JSON response like this ...

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

above JSON , POJO look like this

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

and Retrofit call look like this .....

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

Just combine both of above JSON response into one .....

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

and use Result inside Your API call ......

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

Note:- You directly combine your 2 POJO class and accessing it. (This is very complicate if you have response very large and provide duplication if some KEY is same with different Variable type )

like image 186
sushildlh Avatar answered Sep 25 '22 15:09

sushildlh


You can build main pojo like this

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;     } } 

And call like this

 Call<BaseResponse<SetupDetails>> getSetup(@Query("site_id") int id,@Query("ino") String ii); 
like image 45
Surya Prakash Kushawah Avatar answered Sep 25 '22 15:09

Surya Prakash Kushawah