What is the fix to Synchronous ResponseHandler error in Android?

I’m writing an Android application that, in part, sends put requests to update an API via PUT.

A set of objects looks like this:

{
            "id": "b04caf39-eefd-4221-a6a9-66dd3e80d6a3",
            "room": "338",
            "request": "Send 5 towels to room 338",
            "time": 1501567055,
            "done": false
        },

I’m receiving this error in my log cat:

07-31 22:57:57.683 3597-3597/com.example.duncan.recyclerviewproject E/params: https://summerproject17.herokuapp.com/api/request/b04caf39-eefd-4221-a6a9-66dd3e80d6a3
                                                                              id: b04caf39-eefd-4221-a6a9-66dd3e80d6a3
                                                                              Time: 1501567055
                                                                              Request: Send 5 towels to room 338
                                                                              Room: 338
07-31 22:57:57.686 3597-3597/com.example.duncan.recyclerviewproject E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                      Process: com.example.duncan.recyclerviewproject, PID: 3597
                                                                                      java.lang.IllegalArgumentException: Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead.
                                                                                          at com.loopj.android.http.AsyncHttpClient.sendRequest(AsyncHttpClient.java:1493)
                                                                                          at com.loopj.android.http.AsyncHttpClient.put(AsyncHttpClient.java:1267)
                                                                                          at com.loopj.android.http.AsyncHttpClient.put(AsyncHttpClient.java:1249)
                                                                                          at com.loopj.android.http.AsyncHttpClient.put(AsyncHttpClient.java:1236)
                                                                                          at com.example.duncan.recyclerviewproject.MainAdapter.putLoopjRequest(MainAdapter.java:213)
                                                                                          at com.example.duncan.recyclerviewproject.MainAdapter.access$000(MainAdapter.java:38)
                                                                                          at com.example.duncan.recyclerviewproject.MainAdapter$1.onClick(MainAdapter.java:117)
                                                                                          at android.view.View.performClick(View.java:4780)
                                                                                          at android.view.View$PerformClick.run(View.java:19866)
                                                                                          at android.os.Handler.handleCallback(Handler.java:739)
                                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                          at android.os.Looper.loop(Looper.java:135)
                                                                                          at android.app.ActivityThread.main(ActivityThread.java:5254)
                                                                                          at java.lang.reflect.Method.invoke(Native Method)
                                                                                          at java.lang.reflect.Method.invoke(Method.java:372)
                                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
                                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)

I suspect this snippet of my adapter is the culprit:

    @Override
    public boolean getUseSynchronousMode() {
        return true;
    }

    @Override
    public void setUseSynchronousMode(boolean useSynchronousMode) {

    }

Full adapter can be seen here:

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.ResponseHandlerInterface;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import cz.msebera.android.httpclient.Header;
import cz.msebera.android.httpclient.HttpResponse;


public class MainAdapter extends BaseAdapter {
    SharedPreferences preferences;
    private String PUT_URL="https://summerproject17.herokuapp.com/api/request/";

    Context context;
    ArrayList<ListItem> arraylist=new ArrayList<>();

    public MainAdapter(Context context,
                       ArrayList<ListItem>arrayList){
        this.context=context;
        this.arraylist=arrayList;
    }


    @Override
    public int getCount() {
        return arraylist.size();
    }

    @Override
    public Object getItem(int i) {
        return arraylist.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    public class ViewHolder{
        Button   mark_btn;
        public TextView textViewRoom;
        public TextView textViewRequest;
        public TextView textViewTime;
    }

    @Override
    public View getView(final int position, View row, ViewGroup parent) {
        View convertView=row;
       final ViewHolder holder;
        if(convertView==null) {

            holder=new ViewHolder();
            LayoutInflater infalInflater = (LayoutInflater)
                    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.custom_layout, null);

            holder.mark_btn= (Button) convertView.findViewById(R.id.button);
            holder.textViewRoom = (TextView) convertView.findViewById(R.id.textViewRoom);
            holder.textViewRequest = (TextView) convertView.findViewById(R.id.textViewRequest);
            holder.textViewTime = (TextView) convertView.findViewById(R.id.textViewTime);
            convertView.setTag(holder);
            FontChangerCrawler fontChanger = new FontChangerCrawler(context.getAssets(), "fonts/elegantluxpro-mager.ttf");
            fontChanger.replaceFonts((ViewGroup)convertView);

        }else{
            holder = (ViewHolder) convertView.getTag();

        }

        /*convert UnixTime to Time  youy can get minutes ,hours and seconds too*/

        /*Date time=new java.util.Date((long)Long.parseLong(arraylist.get(position).getTime())*1000);

        time.getSeconds();

        time.getMinutes();

        time.getHours();*/

        final ListItem listItem= (ListItem) getItem(position);

        holder.textViewRoom.setText("Room: "+listItem.getRoom());
        holder.textViewRequest.setText(listItem.getRequest());
        holder.textViewTime.setText("Time: "+listItem.getTime());

        holder.mark_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                putLoopjRequest(listItem.getId(),listItem.getRoom(),listItem.getRequest(), listItem.getTime());
                Toast.makeText(context, "Marked complete", Toast.LENGTH_SHORT).show();
            }
        });

        return convertView;
    }

    private void putRequest(final String id, final String room, final String request, final String time)
    {
        RequestQueue queue = Volley.newRequestQueue(context);
        JSONObject params=new JSONObject();
        try {
            params.put("id", id);
            params.put("room", room);
            params.put("request",request);
            params.put("time",time);
            params.put("done",true);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        JsonObjectRequest putRequest = new JsonObjectRequest(Request.Method.PUT,PUT_URL + id, params, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                Log.e("response",response.toString());
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {

            }
        }

        );
        queue.add(putRequest);
    }
    private  void putVolleyStringRequest(final String id, final String room, final String request, final String time)
    {
        StringRequest putRequest = new StringRequest(Request.Method.PUT, PUT_URL+id,
                new Response.Listener<String>()
                {
                    @Override
                    public void onResponse(String response) {
                        // response
                        Log.d("Response", response.toString());
                    }
                },
                new Response.ErrorListener()
                {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        // error
                        Log.d("Error.Response", error.toString());
                    }
                }
        ) {

            @Override
            public Map<String, String> getHeaders()
            {
                Map<String, String> headers = new HashMap<String, String>();
                headers.put("Content-Type", "application/json");
                //or try with this:
                //headers.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
                return headers;
            }
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<String, String>();
                params.put("id", id);
                params.put("room", room);
                params.put("request",request);
                params.put("time",time);
                params.put("done",String.valueOf("true"));
                return params;
            }
            @Override
            public String getBodyContentType() {
                return "application/json";
            }
        };

        RequestQueue queue=Volley.newRequestQueue(context);
        queue.add(putRequest);
    }

    private void putLoopjRequest(final String id, final String room, final String request, final String time)
    {
        AsyncHttpClient client = new AsyncHttpClient();
        RequestParams params = new RequestParams();
        params.put("id", id);
        params.put("room", room);
        params.put("request",request);
        params.put("time",Integer.parseInt(time));
        params.put("done",true);
        Log.e("params",PUT_URL+id+"/nid: "+id+"/nTime: "+time+"/nRequest: "+request+"/nRoom: "+room);
        client.put(PUT_URL+id, params, new ResponseHandlerInterface() {
            @Override
            public void sendResponseMessage(HttpResponse response) throws IOException {
                Log.e("response",response.toString());
            }

            @Override
            public void sendStartMessage() {

            }

            @Override
            public void sendFinishMessage() {

            }

            @Override
            public void sendProgressMessage(long bytesWritten, long bytesTotal) {

            }

            @Override
            public void sendCancelMessage() {

            }

            @Override
            public void sendSuccessMessage(int statusCode, Header[] headers, byte[] responseBody) {
                Log.e("response","Code is"+statusCode+"/nResponse is: "+responseBody+"");

            }

            @Override
            public void sendFailureMessage(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
                Log.e("response","error"+statusCode+"/nResponse is: "+responseBody+"");
            }

            @Override
            public void sendRetryMessage(int retryNo) {
                Log.e("response","Retry"+retryNo);
            }

            @Override
            public URI getRequestURI() {
                return null;
            }

            @Override
            public void setRequestURI(URI requestURI) {

            }

            @Override
            public Header[] getRequestHeaders() {
                return new Header[0];
            }

            @Override
            public void setRequestHeaders(Header[] requestHeaders) {

            }

            @Override
            public boolean getUseSynchronousMode() {
                return true;
            }

            @Override
            public void setUseSynchronousMode(boolean useSynchronousMode) {

            }

            @Override
            public boolean getUsePoolThread() {
                return false;
            }

            @Override
            public void setUsePoolThread(boolean usePoolThread) {

            }

            @Override
            public void onPreProcessResponse(ResponseHandlerInterface instance, HttpResponse response) {

            }

            @Override
            public void onPostProcessResponse(ResponseHandlerInterface instance, HttpResponse response) {

            }

            @Override
            public Object getTag() {
                return null;
            }

            @Override
            public void setTag(Object TAG) {

            }
        });
    }
    }

The error is pretty explicit in Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead however, I’m still fairly new to android and haven’t found any resources for the best way to implement the fix. What is the best way implement the fix for this error?

This problem was resolved thanks to @Elliott’s suggestion to change true to false, updated code can be seen here:

@Override
    public boolean getUseSynchronousMode() {
        return false;
    }

@Override
    public void setUseSynchronousMode(boolean useSynchronousMode) {

    }