Java – The best way to use a modified response in multiple activities

The best way to use a modified response in multiple activities… here is a solution to the problem.

The best way to use a modified response in multiple activities

I have a function searchForTrips() that sends an API request and gets some response as follows.

private void searchForTrips(){

int departurePortId = PORT_ID_LIST.get(departurePort);
    int returnPortId = PORT_ID_LIST.get(returnPort);
    int pax= Integer.parseInt(noOfPassengers);
    String departureDatePARSED = DEPARTURE_DATE_VALUES.get(departureDate);
    String returnDatePARSED = RETURN_DATE_VALUES.get(departureDate);

Call<TripSearchResponse> call = apiService.searchAvailableTrips(TripType,departurePortId,returnPortId,departureDatePARSED,returnDatePARSED,pax);
    call.enqueue(new Callback<TripSearchResponse>() {
        @Override
        public void onResponse(Call<TripSearchResponse> call, Response<TripSearchResponse> response) {
            int statusCode = response.code();
            switch(statusCode){
                case 200:

default:
                    Snackbar.make(findViewById(android. R.id.content),"Error loading data. Network Error.", Snackbar.LENGTH_LONG).show();
                break;
            }
        }
        @Override
        public void onFailure(Call<TripSearchResponse> call, Throwable t) {
            Log.i(TAG, t.getMessage());
            Snackbar.make(findViewById(android. R.id.content),"Error loading data. Network Error.", Snackbar.LENGTH_LONG).show();
        }
    });

}

The intent is to make this callback function reusable so that I can call it from multiple activities and get the requested data as needed. What is the best way to achieve this?

Solution

Try this way, it’s dynamic way and easy to use:

Create a Retforit interface:

public interface ApiEndpointInterface {

@Headers("Content-Type: application/json")
    @POST(Constants.SERVICE_SEARCH_TRIP)
    Call<JsonObject> searchForTrip(@Body TripRequest objTripRequest);

}

Create a retrofit class:

public class AppEndPoint {

private static Retrofit objRetrofit;

public static ApiEndpointInterface getClient() {
        if (objRetrofit == null){
            objRetrofit = new Retrofit.Builder()
                    .baseUrl(Constants.SERVER_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return objRetrofit.create(ApiEndpointInterface.class);
    }
}

Create this helper class/interface to hold the network service callback:

public enum ResponseState {
    SUCCESS,
    FAILURE,
    NO_CONNECTION
}

public enum RequestType {
    SEARCH_FOR_TRIP // add name for each web service
}

public class Response {
    public ResponseState state;
    public boolean hasError;
    public RequestType requestType;
    public JsonObject result;
}

public interface RestRequestInterface {
    void Response(Response response);
    Context getContext();
}

public class ResponseHolder { used to hold the Json response could be changed as your response

@SerializedName("is_successful")
    @Expose
    private boolean isSuccessful;

@SerializedName("error_message")
    @Expose
    private String errorMessage;

public boolean isSuccessful() {
        return isSuccessful;
    }

public void setSuccessful(boolean successful) {
        isSuccessful = successful;
    }

public String getErrorMessage() {
        return errorMessage;
    }

public void setErrorMessage(String errorMessage) {
        this.errorMessage = errorMessage;
    }
}

public class AppClient {
    private static ApiEndpointInterface objApiEndpointInterface;
    private static Response objResponse;
    private static Call<JsonObject> objCall;

 implement new method like below for each new web service
    public static void searchForTrip(TripRequest objTripRequest, RestRequestInterface objRestRequestInterface) {
        objResponse = new Response();
        objResponse.state = ResponseState.FAILURE;
        objResponse.hasError = true;
        objResponse.requestType = RequestType.SEARCH_FOR_TRIP;  set type of the service from helper interface

objApiEndpointInterface = AppEndPoint.getClient();
        objCall = objApiEndpointInterface.searchForTrip(objTripRequest);
        handleCallBack(objRestRequestInterface);
    }

private static void handleCallBack(final RestRequestInterface objRestRequestInterface) {
        objCall.enqueue(new Callback<JsonObject>() {
            @Override
            public void onResponse(Call<JsonObject> call, retrofit2. Response<JsonObject> response) {
                try {
                    ResponseHolder objResponseHolder = new Gson().fromJson(response.body(), ResponseHolder.class);
                    if (objResponseHolder.isSuccessful()) {
                        objResponse.state = ResponseState.SUCCESS;
                        objResponse.hasError = false;
                        objResponse.result = response.body();
                    } else {
                        objResponse.errorMessage = objResponseHolder.getErrorMessage();
                    }
                    objRestRequestInterface.Response(objResponse);

} catch (Exception objException) {
                    objResponse.errorMessage = objRestRequestInterface.getContext().getString(R.string.server_error);
                    objRestRequestInterface.Response(objResponse);
                }
            }

@Override
            public void onFailure(Call<JsonObject> call, Throwable objThrowable) {
                String errorMessage = "";
                if (objThrowable instanceof IOException) {
                    errorMessage = objRestRequestInterface.getContext().getString(R.string.no_connection_error);
                } else {
                    errorMessage = objRestRequestInterface.getContext().getString(R.string.server_error);
                }
                objResponse.errorMessage = errorMessage;
                objRestRequestInterface.Response(objResponse);
            }
        });
    }
}

Then go to your fragment activity and call it like this:

public class MainActivity extends AppCompatActivity implements RestRequestInterface {

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

 initialize ids

 prepare to call web service

 1.Initialize your object to be sent over web service
        TripRequest objTripRequest = new TripRequest();
        objTripRequest.id = 1;

 2.Show loader

 3.Make the call
        AppClient.searchForTrip(objTripRequest, this);
    }

@Override
    public void Response(Response response) {
         hide loader
        try {
            if (response.state == ResponseState.SUCCESS && !response.hasError) {
                 check the type of web service
                if (response.requestType == RequestType.SEARCH_FOR_TRIP) {
                     acces the return here from  response.result
                }
            } else {
                String errorMsg = response.hasError ? response.errorMessage : getString(R.string.no_connection_error);
                 show the error to the user
            }
        } catch (Exception objException) {
             show the error to the user
        }
    }

@Override
    public Context getContext() {
         do not forgit set the context here
         if fragment replace with getAcitvity();
        return this;
    }
}

Related Problems and Solutions