web-dev-qa-db-ja.com

Android loopj AsyncHttpが1.4.5アップデート後にクラッシュする

Android loopj Async Http libがリリースされ、大幅に変更されました。手動でLooper.prepare()を設定する必要があります。そうしないと、デフォルトで非同期ではなく同期モードが使用されます。設定する必要がある場所がわかりません。

Logcat

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

そのメッセージの後、それは完全にクラッシュします

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

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

誰か助けてもらえますか?

16
Phil

同様の問題があり、スレッド内の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;
  }
}
33
Paul T.

私はそれをパウロのやり方で行うことに同意しません。私が提示しようとしている方法もかなりハッキーなので、これを回避するための良い方法を実際に見ることはできませんが、AsyncHttpResponseHandlerを使用する代わりに、代わりにこのクラスを使用してください

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

1つのコード行で解決します

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


        } ;

そしてこれは聖なる線でした

responseHandler.setUsePoolThread(true);
5
angel

このようにAsyncHttpResponseHandler(Looper.getMainLooper())にパラメーターを渡すことで問題を解決しました。

まず、2つのクラスを使用しました。1つはMainActivityとDownloadクラスです。 MainActivityクラスでは、Downloadclassに実装されているpostメソッドを呼び出します。次に、ダウンロードクラスにはPOST()が含まれます。これはimportcom.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.C​​lass

    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

このバージョンにはいくつかのバグがあるためです。

OkHttp非同期レイヤーを使用することを強くお勧めします。基本的に同じ構造です。

または、OkHttpClient(Square Inc)に基づく同じ構造が必要な場合は、次を使用します。

https://github.com/leonardoxh/AsyncOkHttpClient

0
Leonardo