Retrofit calls are adding up
<p>I have a button in my application for logging out the user's session , when it is clicked retrofit sends a basic POST request to the localhost and technically it is logged out , but if i click the logout button again the following happens:</p>

<p>1st time : one request goes through
2nd time click logout : 2 requests are made for logout at same time
3rd time click logout : 3 requests are made for logout </p>

<p>and so on ..</p>

<p>Honestly , this situation is very puzzling to me and yes i use retrofit with okhttp interceptors and some token management .</p>

<p>Note : - (Tinydb is a simple shared preference manager)</p>

<p>Code posted below:</p>

<p><strong>ApiInterfacer.java</strong> - This is my api interface</p>

<pre><code>@FormUrlEncoded
@POST("/api/token/logout")
Call&lt;BasicResponse&gt; LOG_OUT(@Field("guid") String guid);
</code></pre>

<p><strong>ApiService.java</strong> - My Api service creator</p>

<pre><code>public class ApiService {

public static final String baseurl = StaticVars.LOCALHOST;
public static OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
private static Retrofit.Builder retrofitbuilder = new Retrofit.Builder().baseUrl(baseurl).addConverterFactory(GsonConverterFactory.create());

public static &lt;S&gt;S createService(Class&lt;S&gt; serviceClass , Context context) // service class is the REST class , ex : GithubClient
{

    Retrofit retrofit = retrofitbuilder.build();
    httpClientBuilder.interceptors().add(new ApiTokenInterceptor(context));
    OkHttpClient client = httpClientBuilder.build();
    retrofitbuilder.client(client);
    return retrofit.create(serviceClass);

}

}
</code></pre>

<p><strong>ApiTokenInterceptor.java</strong></p>

<pre><code>public class ApiTokenInterceptor implements Interceptor {

private final Context context;
public ApiTokenInterceptor(Context context){

    this.context = context;
}

@Override
public Response intercept(Chain chain) throws IOException {

    Log.i("INTERCEPT" , "FIRST " + chain.request().url());
    TinyDB db = new TinyDB(context);
    Request request = chain.request();
    Request modifiedReq = request;
    if(!db.getString("token").equals(""))
    {
        modifiedReq = request.newBuilder().addHeader("token" ,db.getString("token"))
                .build();
    }

    Response response = chain.proceed(modifiedReq);
    boolean unauthorized = response.code() == 401;
    Log.i("INTERCEPT" , "SECOND - LOGOUT - PROCEED " + modifiedReq.url() + " " + unauthorized);
    if(unauthorized){
        response.body().close();
        db.remove("token");
        String refreshToken = db.getString("refken");

        Request request1 = new Request.Builder()
                .url(StaticVars.LOCALHOST + "/api/token")
                .addHeader("refken" , refreshToken)
                .get()
                .build();
        OkHttpClient client = new OkHttpClient();
        Response response1 = client.newCall(request1).execute();
        String response_string = response1.body().string();
        Log.d("INTERCEPT" , "RESPONSE TOKEN STRING "  + response_string);
        try{
            JSONObject object = new JSONObject(response_string);
            String token = object.getString("token");
            //set token to db
            Log.d("TOKENB" , " "+token);
            db.putString("token" , token);
        }catch (JSONException e){
            e.printStackTrace();
            Log.d("INVALID RESPONSE" , " "+response_string);
            db.putString("token" , "placeholder");
            Log.i("INTERCEPT" , "AFINAL - LOGOUT - PROCEED " + modifiedReq.url());
            return response;
        }

        modifiedReq = request.newBuilder().addHeader("token" , db.getString("token"))
                .build();
        Log.i("INTERCEPT" , "BFINAL - LOGOUT - PROCEED " + modifiedReq.url());
        return chain.proceed(modifiedReq);
    }

    return response;

}


}
</code></pre>

<p><strong>(Usage).java</strong> - usage takes place in onclicklistener of a button</p>

<pre><code>retro.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {


            //call retrofit :)
            final ProgressDialog pd = new ProgressDialog(v.getContext());
            pd.setMessage("Loading...");
            pd.setCancelable(false);
            pd.setIndeterminate(true);
            pd.show();
            ApiInterfacer client = ApiService.createService(ApiInterfacer.class, v.getContext());
            Call&lt;BasicResponse&gt; call = client.LOG_OUT(db.getString("guid"));
            call.enqueue(new Callback&lt;BasicResponse&gt;() {
                @Override
                public void onResponse(Call&lt;BasicResponse&gt; call, Response&lt;BasicResponse&gt; response) {
                    Log.d("Response : string" , "" + response.message());
                    switch(response.code())
                    {
                        case 401:
                            Log.d("LOGOUT" , "Unauthorized : "+401);
                            break;
                        case 400:
                            Log.d("LOGOUT" , "Malformed Body : " + 400);
                            break;
                        case 404:
                            Log.d("LOGOUT" , "URL Not Found :" + 404);
                            break;
                        case 200:
                            Log.d("Message" ,""+ response.body().getMessage()+" "+response.body().getCode());
                            if(response.body().getCode().equals("LOGGEDOUT"))
                            {
                                db.remove("token");
                                db.remove("refken");
                                startActivity(new Intent(getActivity(), LoginActivity.class));
                                getActivity().finish();
                            }
                            break;
                        default:
                            BasicResponse resp = response.body();
                            if(resp==null)
                            {
                                Log.d("Error" , "Response is null : " + response.code());
                            }else {
                                Log.d("Code", "" + resp.getCode());
                                Log.d("Source", "" + resp.getSource());
                                Log.d("Message", "" + resp.getMessage());
                                Log.d("Error", "" + resp.getError());
                            }
                    }

                    if(!call.isCanceled()) {
                        Log.i("INTERCEPT" , "FORCE CANCEL");
                        call.cancel();
                    }
                    pd.cancel();
                }

                @Override
                public void onFailure(Call&lt;BasicResponse&gt; call, Throwable t) {
                    t.printStackTrace();
                    pd.cancel();
                    //page divert intent
                    Toast.makeText(v.getContext() , "Could not connect to server" , Toast.LENGTH_SHORT).show();
                    Log.d("FAIL" , ""+t.getMessage());

                    if(!call.isCanceled()) {
                        Log.i("INTERCEPT" , "FORCE CANCEL");
                        call.cancel();
                    }
                }
            });

        }
    });
</code></pre>

<p>LOG : - </p>

<pre><code>1st click : ( 0 * FIRST - Run at starting of interceptor ? interceptor not     running ?? )
09-13 00:40:04.657 29600-29600/some.example.okhttp I/INTERCEPT: FORCE CANCEL

2nd click : ( 1 * FIRST - Run at starting of interceptor )
09-13 00:41:45.156 29600-31375/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:41:45.166 29600-31375/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout false
09-13 00:41:45.217 29600-29600/some.example.okhttp I/INTERCEPT: FORCE CANCEL

3rd click: ( 3 * FIRST ) 
09-13 00:41:54.364 29600-31375/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:41:54.364 29600-31375/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:41:54.370 29600-31375/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout true
09-13 00:41:54.382 29600-31375/some.example.okhttp I/INTERCEPT: BFINAL - LOGOUT - PROCEED http://192.168.2.2/api/token/logout
09-13 00:41:54.431 29600-31375/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout true
09-13 00:41:54.454 29600-31375/some.example.okhttp I/INTERCEPT: BFINAL - LOGOUT - PROCEED http://192.168.2.2/api/token/logout
09-13 00:41:54.454 29600-31375/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:41:54.466 29600-31375/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout true
09-13 00:41:54.503 29600-31375/some.example.okhttp I/INTERCEPT: BFINAL - LOGOUT - PROCEED http://192.168.2.2/api/token/logout
09-13 00:41:54.695 29600-29600/some.example.okhttp I/INTERCEPT: FORCE CANCEL

4th click: ( 7 * FIRST )
09-13 00:42:57.726 29600-32408/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:42:57.726 29600-32408/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:42:57.726 29600-32408/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:42:57.731 29600-32408/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout true
09-13 00:42:57.740 29600-32408/some.example.okhttp I/INTERCEPT: BFINAL - LOGOUT - PROCEED http://192.168.2.2/api/token/logout
09-13 00:42:57.779 29600-32408/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout true
09-13 00:42:57.819 29600-32408/some.example.okhttp I/INTERCEPT: BFINAL - LOGOUT - PROCEED http://192.168.2.2/api/token/logout
09-13 00:42:57.819 29600-32408/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:42:57.831 29600-32408/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout true
09-13 00:42:57.865 29600-32408/some.example.okhttp I/INTERCEPT: BFINAL - LOGOUT - PROCEED http://192.168.2.2/api/token/logout
09-13 00:42:57.892 29600-32408/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout true
09-13 00:42:57.942 29600-32408/some.example.okhttp I/INTERCEPT: BFINAL - LOGOUT - PROCEED http://192.168.2.2/api/token/logout
09-13 00:42:57.942 29600-32408/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:42:57.942 29600-32408/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:42:57.968 29600-32408/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout true
09-13 00:42:58.006 29600-32408/some.example.okhttp I/INTERCEPT: BFINAL - LOGOUT - PROCEED http://192.168.2.2/api/token/logout
09-13 00:42:58.029 29600-32408/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout true
09-13 00:42:58.053 29600-32408/some.example.okhttp I/INTERCEPT: BFINAL - LOGOUT - PROCEED http://192.168.2.2/api/token/logout
09-13 00:42:58.053 29600-32408/some.example.okhttp I/INTERCEPT: FIRST http://192.168.2.2/api/token/logout
09-13 00:42:58.086 29600-32408/some.example.okhttp I/INTERCEPT: SECOND - LOGOUT - PROCEED http://192.168.2.2/api/token/logout true
09-13 00:42:58.152 29600-32408/some.example.okhttp I/INTERCEPT: BFINAL - LOGOUT - PROCEED http://192.168.2.2/api/token/logout
09-13 00:42:58.245 29600-29600/some.example.okhttp I/INTERCEPT: FORCE CANCEL
</code></pre>