Retrofit "IllegalStateException: Already executed"

13,153

A Call can only be used once. Its documentation tells you how to use one multiple times:

Use clone() to make multiple calls with the same parameters to the same webserver; this may be used to implement polling or to retry a failed call.

So use call.clone().enqueue(..) for Asynchornous and call.clone().execute() for Synchornous respectively to ensure that you have a fresh, unexecuted Call for each request.

Share:
13,153
Orbit
Author by

Orbit

Updated on June 25, 2022

Comments

  • Orbit
    Orbit almost 2 years

    I have a Retrofit network call that id like to run every 5 seconds. My current code:

    Handler h = new Handler();
    int delay = 5000; //milliseconds
    
    h.postDelayed(new Runnable() {
        public void run() {
            call.enqueue(new Callback<ApiResponse>() {
                @Override
                public void onResponse(Response<ApiResponse> response) {
                    Log.d("api", "response: " + response.body().getPosition().getLatitude().toString());
                }
    
                @Override
                public void onFailure(Throwable t) {
    
                }
            });
            h.postDelayed(this, delay);
        }
    }, delay);
    

    This runs once, but then throws the following:

    java.lang.IllegalStateException: Already executed. at retrofit2.OkHttpCall.enqueue(OkHttpCall.java:52) at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.enqueue(ExecutorCallAdapterFactory.java:57) at orbyt.project.MyFragment$1.run(MyFragment.java:93)

    Whats the issue here?

    As a bonus: whats a better way to handle this? Ill be updating a map every update. I was thinking about trying to use Rx but not sure if this is an appropriate use-case, or how to implement it.