我正在编写一个Android应用程序,它部分地通过PUT
发送put请求来更新API。
一组对象如下所示:
{
"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建议将true
更改为false
,此问题已得到解决,更新代码可在此处查看:
@Override
public boolean getUseSynchronousMode() {
return false;
}
@Override
public void setUseSynchronousMode(boolean useSynchronousMode) {
}