2017-08-01 69 views
0

我正在编写一个Android应用程序,它部分通过PUT发送放置请求来更新API。Android中的Synchronous ResponseHandler错误的修复程序是什么?

一组对象看起来是这样的:

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

我在我的日志猫收到此错误:

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) 

我怀疑我的适配器的这段代码是罪魁祸首:

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

    @Override 
    public void setUseSynchronousMode(boolean useSynchronousMode) { 

    } 

完整的适配器可以在这里看到:

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) { 

      } 
     }); 
    } 
    } 

这个错误在Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead中很明显,但是我还是比较新的android,并没有找到任何资源来实现修复的最佳方式。实施此错误的最佳方法是什么?

+0

您应该发布一些更多的适配器代码,或超类的至少是适配器,所以我们可以更轻松地解读您的代码段。 –

+0

@Elliott我已经添加了适用于上下文的完整适配器。最初是因为我不想让这个问题太长,除非有必要。 – hackerman

+0

我同意'getUseSynchronousMode'方法是罪魁祸首。似乎你必须至少从该方法中返回“假”,以使事情能够发挥作用。 –

回答

0

,此问题已得到解决感谢@艾略特的建议,改变truefalse,更新的代码可以在这里看到:

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

@Override 
    public void setUseSynchronousMode(boolean useSynchronousMode) { 

    } 
相关问题