Android loopj Async Http падает после обновления 1.4.5
Новое обновление для Android loopj Async Http lib отсутствует, и они сильно изменились. Теперь вам нужно вручную установить Looper.prepare()
, иначе он использует синхронный режим вместо async по умолчанию. Я не понимаю, где мне нужно его установить.
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);
}
}
Кто-нибудь может мне помочь?
Ответы
Ответ 1
У меня была аналогичная проблема, и я обнаружил, что создание HTTP-запросов с AsyncHttpClient в потоке вызвало проблему.
Я выполнил свой 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;
}
}
Ответ 2
Я не согласен с тем, как это делал Павел. Хотя я не могу видеть хороший способ обойти это, поскольку способ, которым я собираюсь представить, довольно хакен, но вместо того, чтобы использовать AsyncHttpResponseHandler, используйте этот класс вместо
public abstract class AlwaysAsyncHttpResponseHandler extends AsyncHttpResponseHandler {
@Override
public boolean getUseSynchronousMode() {
return false;
}
}
Ответ 3
Я решил проблему, передав параметр в AsyncHttpResponseHandler (Looper.getMainLooper()), как это.
Прежде всего, я использовал два класса: MainActivity и Download Class. В классе MainActivity я вызываю метод post, который реализуется в DownloadClass. Тогда класс Download содержит 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");
}
});
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 );
}
Ответ 4
Я решаю его с помощью одной строки кода
Я отделил свой ответHandler
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
Это потому, что в этой версии есть несколько ошибок.
Я высоко рекомендую вам использовать асинхронный слой OkHttp, это в основном та же структура.
Или, если вы хотите, чтобы одна и та же структура, основанная на OkHttpClient (Square Inc), использовала это:
https://github.com/leonardoxh/AsyncOkHttpClient