2014-07-09 2 views
16

Android loopj Async Http lib에 대한 새 업데이트가 출시되었습니다. 이제 수동으로 Looper.prepare()을 설정해야합니다. 그렇지 않으면 기본적으로 비동기 모드 대신 동기 모드가 사용됩니다. 나는 그것을 설정해야 할 곳을 찾지 못한다.Android loopj 1.4.5 업데이트 후 비동기 Http 충돌이 발생합니다.

import android.os.Looper; 

import com.loopj.android.http.AsyncHttpClient; 
import com.loopj.android.http.AsyncHttpResponseHandler; 
import com.loopj.android.http.PersistentCookieStore; 
import com.loopj.android.http.RequestParams; 

public class HttpRequest { 
     public static AsyncHttpClient client = new AsyncHttpClient(); 

     public static void setCookieStore(PersistentCookieStore cookieStore) { 
      client.setCookieStore(cookieStore); 
     } 

     public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { 
      Looper.prepare(); 
      client.get(url, params, responseHandler); 
     } 

     public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { 
      Looper.prepare(); 
      client.post(url, params, responseHandler); 
     } 
} 

이 사람이 나를 도울 수 : 해당 메시지 후

로그 캣

07-09 08:16:18.775: W/AsyncHttpResponseHandler(6606): Current thread has not called Looper.prepare(). Forcing synchronous mode. 

는 완전히 HTTP 요청에 대한

07-09 08:16:18.835: E/AndroidRuntime(6606): FATAL EXCEPTION: AsyncTask #1 
07-09 08:16:18.835: E/AndroidRuntime(6606): java.lang.RuntimeException: An error occured while executing doInBackground() 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at android.os.AsyncTask$3.done(AsyncTask.java:278) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at java.lang.Thread.run(Thread.java:864) 
07-09 08:16:18.835: E/AndroidRuntime(6606): Caused by: java.lang.IllegalArgumentException: Synchronous ResponseHandler used in AsyncHttpClient. You should create your response handler in a looper thread or use SyncHttpClient instead. 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at com.loopj.android.http.AsyncHttpClient.sendRequest(AsyncHttpClient.java:1096) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at com.loopj.android.http.AsyncHttpClient.post(AsyncHttpClient.java:873) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at com.loopj.android.http.AsyncHttpClient.post(AsyncHttpClient.java:856) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at com.loopj.android.http.AsyncHttpClient.post(AsyncHttpClient.java:843) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at com.xxx.app.HttpRequestGCM.post(HttpRequestGCM.java:15) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at com.xxx.app.ChatActivity$RegisterBackground.sendRegistrationIdToBackend(ChatActivity.java:681) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at com.xxx.app.ChatActivity$RegisterBackground.doInBackground(ChatActivity.java:660) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at com.xxx.app.ChatActivity$RegisterBackground.doInBackground(ChatActivity.java:1) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at android.os.AsyncTask$2.call(AsyncTask.java:264) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
07-09 08:16:18.835: E/AndroidRuntime(6606):  ... 5 more 

내 클래스를 충돌?

답변

0

이 버전에는 몇 가지 버그가 있기 때문입니다.

내가 좋습니다. OkHttp 비동기 레이어를 사용하는 것이 좋습니다. 기본적으로 동일한 구조입니다. 당신이 OkHttpClient (광장 Inc의)를 기반으로 동일한 구조를 원하는 경우

또는이를 사용

https://github.com/leonardoxh/AsyncOkHttpClient

+3

방금 ​​문제를 발견했습니다. GCM 등록 프로세스 때문입니다. 이 프로세스가 실제로 AsyncTask에 있기 때문에 Async를 Sync로 변경 했으므로 Sync가 중요하지는 않습니다. – Phil

+0

1 년 후 의견이 있으십니까?나는 네가 화났다고 생각해. – Leonardo

+0

나는이 대답이 전혀 유익하지 않기 때문에 나는 downvoted. "몇 가지 버그가 있습니다. 프레임 워크를 전환해야합니다." 첫 번째는 명백하게 보이고 두 번째는 비 연속입니다. –

33

을 나는 비슷한 문제가 있었다 및 스레드에 AsyncHttpClient로 HTTP 요청을하는 것은 문제의 원인 발견 .

스레드 외부에서 HTTP 요청을 실행하여 문제가 해결되었습니다. 다음과 같이 시도 할 수 있습니다.

public class HttpRequest { 

    // A SyncHttpClient is an AsyncHttpClient 
    public static AsyncHttpClient syncHttpClient= new SyncHttpClient(); 
    public static AsyncHttpClient asyncHttpClient = new AsyncHttpClient(); 

    public static void setCookieStore(PersistentCookieStore cookieStore) { 
     getClient().setCookieStore(cookieStore); 
    } 

    public static void get(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { 
     getClient().get(url, params, responseHandler); 
    } 

    public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) { 
     getClient().post(url, params, responseHandler); 
    } 

    /** 
    * @return an async client when calling from the main thread, otherwise a sync client. 
    */ 
    private static AsyncHttpClient getClient() 
    { 
     // Return the synchronous HTTP client when the thread is not prepared 
     if (Looper.myLooper() == null) 
      return syncHttpClient; 
     return asyncHttpClient; 
    } 
} 
+0

효과가있었습니다! 라이브러리를 전환하는 것보다 낫습니다. –

+0

하지만 루퍼를 제대로 준비하는 방법과 어디에서 설정해야할까요? 비동기 모드를 사용하고 싶습니다. – Ravi

+1

SyncHttpClient를 사용하지 않으려면 어떻게해야합니까? –

12

폴의 방식과 일치하지 않습니다. 내가 제시하려고 해요 방법뿐만 아니라 매우 해키으로 정말이 주위에 얻을 수있는 좋은 방법을 볼 수 있지만, 대신 AsyncHttpResponseHandler이 클래스를 사용할 사용하는 수는 없지만 대신

public abstract class AlwaysAsyncHttpResponseHandler extends AsyncHttpResponseHandler { 
    @Override 
    public boolean getUseSynchronousMode() { 
     return false; 
    } 
} 
+0

이 솔루션은 나를 위해 일했습니다. 스레드에서 비동기 요청을 시작하려고했습니다 (곧 죽을 것입니다). 이 스레드에서 다른 동기식 호출이 있지만이 호출에 대해 비동기를 원했고 위에서 언급 한 메서드를 재정의 할 때까지 예외가 발생했습니다. Tyler에게 감사드립니다. – Rodrigo

+0

간단한 솔루션 ... –

2

나는하여 문제를 해결 AsyncHttpResponseHandler (Looper.getMainLooper())의 매개 변수를 전달하는 것과 같습니다.

우선 MainActivity와 Download Class라는 두 클래스를 사용했습니다. MainActivity 클래스에서 나는 Download 클래스에서 구현되는 post 메서드를 호출합니다. 그런 다음 Download 클래스에는 import com.loopj.android.http. *;와 같이 내 라이브러리에서 가져온 POST()가 포함되어 있습니다.

는 MainActivity.Class

clientObj.post(context,url,entity, "application/json", new AsyncHttpResponseHandler(Looper.getMainLooper()) { 

@Override 
public void onSuccess(int statusCode,org.apache.http.Header[] headers,byte[] responseBody) { 
     System.out.println(" Success ="+responseBody); 
} 
@Override 
public void onFailure(int statusCode,org.apache.http.Header[] headers,byte[] responseBody, Throwable error) { 
    System.out.println("Failure"); 
} 
}); 

DownLoad.Class는

AsyncHttpClient asynClient = new AsyncHttpClient(); 


void post(Context context,String url, StringEntity entity,String string, AsyncHttpResponseHandler asyncHttpResponseHandler) { 
    asynClient.addHeader("Accept", "application/json"); 
    asynClient.addHeader("Content-type", "application/json"); 
    asynClient.post(context, url, entity, "application/json", asyncHttpResponseHandler); 
} 
2

나는 내 ResponseHandler에

JsonHttpResponseHandler responseHandler = new JsonHttpResponseHandler(){ 


      @Override 
      public void onSuccess(int statusCode, Header[] headers, JSONObject response) { 
       RecorridoResponseDTO respuesta= new Gson().fromJson(response.toString(), RecorridoResponseDTO.class); 
       recorrido.setRecorridoId(respuesta.getA()); 
       mDataManager.actualizarRecorrido(recorrido); 
       try { 
        Thread.sleep(10000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

      } 


      @Override 
      public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) { 
       super.onFailure(statusCode, headers, throwable, errorResponse); 
      } 


     } ; 

을 분리 이것이이었다

하나 개의 코드 라인으로 해결 거룩한 line

responseHandler.setUsePoolThread(true);