web-dev-qa-db-fra.com

Boucle Android Async Http se bloque après la mise à jour 1.4.5

La nouvelle mise à jour pour Android loopj Async Http lib est sortie et ils ont beaucoup changé. Maintenant, vous devez définir manuellement Looper.prepare() sinon le mode synchrone est utilisé au lieu du mode asynchrone par défaut. Je ne comprends pas où je dois le régler.

Logcat

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

Après ce message, il se bloque totalement

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

Mon cours pour la requête 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);
      }
}

Quelqu'un peut-il m'aider?

16
Phil

J'ai eu un problème similaire et j'ai constaté que le fait de faire des requêtes HTTP avec AsyncHttpClient dans un thread était à l'origine du problème.

J'ai exécuté ma demande HTTP en dehors du thread et cela a résolu le problème pour moi. Vous pouvez essayer quelque chose comme:

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;
  }
}
33
Paul T.

Je ne suis pas d'accord avec Paul. Bien que je ne puisse pas vraiment voir un bon moyen de contourner cela, la façon dont je vais présenter est assez bidirectionnelle également, mais au lieu d'utiliser AsyncHttpResponseHandler, utilisez plutôt cette classe

public abstract class AlwaysAsyncHttpResponseHandler extends AsyncHttpResponseHandler {
    @Override
    public boolean getUseSynchronousMode() {
        return false;
    }
}
12
Tyler Davis

Je le résous avec une ligne de code

J'ai séparé ma réponseHandler 

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);
            }


        } ;

et c'était la ligne sainte 

responseHandler.setUsePoolThread(true);
4
angel

J'ai résolu le problème en passant le paramètre dans AsyncHttpResponseHandler (Looper.getMainLooper ()) comme ceci.

Tout d'abord, j'ai utilisé deux classes, l'une est MainActivity et Download Class. Dans la classe MainActivity, j’appelle la méthode post qui est implémentée dans la classe de téléchargement. Ensuite, la classe Download contient POST () qui était importé de ma bibliothèque comme import com.loopj.Android.http. *;

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
Ashok

C'est parce que cette version a plusieurs bugs.

Je recommande fortement d'utiliser la couche asynchrone OkHttp, elle est fondamentalement la même.

Ou si vous voulez la même structure basée sur OkHttpClient (Square Inc), utilisez ceci:

https://github.com/leonardoxh/AsyncOkHttpClient

0
Leonardo