I'm trying to return a value that i get from onResponse method in retrofit call request, is there a way that i can get that value out of the overrided method? here is my code: 
public JSONArray RequestGR(LatLng start, LatLng end)
    {
       final JSONArray jsonArray_GR;
        EndpointInterface loginService = ServiceAuthGenerator.createService(EndpointInterface.class);    
        Call<GR> call = loginService.getroutedriver();
        call.enqueue(new Callback<GR>() {
            @Override
            public void onResponse(Response<GR> response , Retrofit retrofit)
            {
                 jsonArray_GR = response.body().getRoutes();
//i need to return this jsonArray_GR in my RequestGR method
            }
            @Override
            public void onFailure(Throwable t) {
            }
        });
        return jsonArray_GR;
    }
i can't get the value of jsonArray_GR because to be able to use it in onResponse method i need to declare it final and i can't give it a value.
The problem is you are trying to synchronously return the value of enqueue, but it is an asynchronous method using a callback so you can't do that. You have 2 options:
RequestGR method to accept a callback and then chain the enqueue callback to it. This is similar to mapping in frameworks like rxJava.This would look roughly like:
public void RequestGR(LatLng start, LatLng end, final Callback<JSONArray> arrayCallback)
    {
        EndpointInterface loginService = ServiceAuthGenerator.createService(EndpointInterface.class);    
        Call<GR> call = loginService.getroutedriver();
        call.enqueue(new Callback<GR>() {
            @Override
            public void onResponse(Response<GR> response , Retrofit retrofit)
            {
                 JSONArray jsonArray_GR = response.body().getRoutes();
                 arrayCallback.onResponse(jsonArray_GR);
            }
            @Override
            public void onFailure(Throwable t) {
               // error handling? arrayCallback.onFailure(t)?
            }
        });
    }
The caveat with this approach is it just pushes the async stuff up another level, which might be a problem for you.
BlockingQueue, Promise or an Observable or even your own container object (be careful to be thread safe) that allows you to check and set the value.This would look like:
public BlockingQueue<JSONArray> RequestGR(LatLng start, LatLng end)
    {
        // You can create a final container object outside of your callback and then pass in your value to it from inside the callback.
        final BlockingQueue<JSONArray> blockingQueue = new ArrayBlockingQueue<>(1);
        EndpointInterface loginService = ServiceAuthGenerator.createService(EndpointInterface.class);    
        Call<GR> call = loginService.getroutedriver();
        call.enqueue(new Callback<GR>() {
            @Override
            public void onResponse(Response<GR> response , Retrofit retrofit)
            {
                 JSONArray jsonArray_GR = response.body().getRoutes();
                 blockingQueue.add(jsonArray_GR);
            }
            @Override
            public void onFailure(Throwable t) {
            }
        });
        return blockingQueue;
    }
You can then synchronously wait for your result in your calling method like this:
BlockingQueue<JSONArray> result = RequestGR(42,42);
JSONArray value = result.take(); // this will block your thread
I would highly suggest reading up on a framework like rxJava though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With