【问题标题】:Android loopj Async Http crashes after 1.4.5 updateAndroid loopj Async Http 在 1.4.5 更新后崩溃
【发布时间】:2014-07-09 06:22:00
【问题描述】:

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

谁能帮帮我?

【问题讨论】:

    标签: java android asynchronous httprequest loopj


    【解决方案1】:

    我遇到了类似的问题,发现在线程中使用 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;
      }
    }
    

    【讨论】:

    • 但是如何正确准备活套以及在哪里设置我想我们想使用异步模式
    • 不想使用SyncHttpClient怎么办?
    • Ravi 您可以调用 Looper.prepare() 或者您可以将 HTTP 请求调用包装在“runOnUIThread”中,具体取决于您要从哪里进行调用。 @Lucas 如果您不想使用 SyncHttpClient,那么您可以在线程/AsyncTasks 之外发出 HTTP 请求。
    【解决方案2】:

    我不同意保罗的做法。虽然我真的看不出解决这个问题的好方法,因为我即将介绍的方式也相当老套,但不要使用 AsyncHttpResponseHandler 而是使用这个类

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

    【讨论】:

    • 这个解决方案对我有用。我试图从一个线程启动一个异步请求(很快就会死掉)。我在这个线程中有其他同步调用,但是对于这个调用,我想要异步并且它给了我一个异常,直到我覆盖了提到的方法。谢谢泰勒。
    【解决方案3】:

    我用一行代码就解决了

    我分离了我的 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);
    

    【讨论】:

    • 谢谢!那真的是圣言。
    【解决方案4】:

    我通过像这样在 AsyncHttpResponseHandler(Looper.getMainLooper()) 中传递参数解决了这个问题。

    首先我使用了两个类,一个是 MainActivity 和下载类。在 MainActivity 类中,我调用了在 Downloadclass 中实现的 post 方法。然后下载类包含从我的库中导入的 POST (),例如 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");
    }
    });
    

    下载.类

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

    【讨论】:

      【解决方案5】:

      这是因为这个版本有几个错误。

      我强烈推荐你使用 OkHttp 异步层,它的结构基本相同。

      或者,如果您想要基于 OkHttpClient (Square Inc) 的相同结构,请使用:

      https://github.com/leonardoxh/AsyncOkHttpClient

      【讨论】:

      • 我刚刚发现了问题。这是因为 GCM 的注册过程。我只是将 Async 更改为 Sync,因为这个过程实际上是在 AsyncTask 中,所以它是否是 Sync 无关紧要
      • 评论后 1 年?我觉得你疯了。
      • 我投了反对票,因为这个答案根本没有信息。 “你有几个错误。你应该切换框架。”第一个似乎很明显,第二个不合逻辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-20
      • 2019-07-25
      • 2023-04-01
      • 1970-01-01
      相关资源
      最近更新 更多