Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android loopj Async Http crashes after 1.4.5 update

The new update for Android loopj Async Http lib is out and they changed a lot. Now you need to manually set Looper.prepare() otherwise it uses synchronious mode instead of async by default. I don't get where I need to set it.

Logcat

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

After that message it totally crashes

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

My class for the Http Request:

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

Can anyone help me?

like image 694
Phil Avatar asked Jul 09 '14 06:07

Phil


2 Answers

I had a similar issue and found that making HTTP requests with an AsyncHttpClient in a thread caused the problem.

I ran my HTTP request outside of the thread and it fixed the problem for me. You can try something like:

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;
  }
}
like image 110
Paul T. Avatar answered Sep 21 '22 05:09

Paul T.


I disagree with doing it Paul's way. Although I can't really see a good way to get around this as the way I'm about to present is fairly hacky as well, but instead of using AsyncHttpResponseHandler use this class instead

public abstract class AlwaysAsyncHttpResponseHandler extends AsyncHttpResponseHandler {
    @Override
    public boolean getUseSynchronousMode() {
        return false;
    }
}
like image 43
Tyler Davis Avatar answered Sep 19 '22 05:09

Tyler Davis