AndroidAsyncHttp 临时修复 JsonHttpResponseHandler 避免死循环

简介:

由于 AndroidAsyncHttp 1.4.4 的 JsonHttpResponseHandler  存在死循环的 BUG,1.4.5 版本发布不知道要何时,所以只能临时替换该类来修复这个错误。

Android开源库loopj的android-async-http的 JsonHttpResponseHandler 存在死循环GC_CONCURRENT


package com.ai9475.extend;

import com.ai9475.meitian.AppManager;
import com.ai9475.meitian.R;
import com.loopj.android.http.JsonHttpResponseHandler;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.util.Log;

import org.apache.http.Header;
import org.apache.http.HttpStatus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;

import java.io.UnsupportedEncodingException;

/**
 * 复写 AndroidAsyncHttp 1.4.4 开源库的 JsonHttpResponseHandler 类
 * 当 1.4.5 released 后失效
 *
 * Created by ZHOUZ on 2014/3/22.
 */
public class ZJsonHttpResponseHandler extends JsonHttpResponseHandler
{
    private static final String LOG_TAG = "JsonHttpResponseHandler";

    /**
     * Returns when request succeeds
     *
     * @param statusCode http response status line
     * @param headers    response headers if any
     * @param response   parsed response if any
     */
    public void onSuccess(int statusCode, Header[] headers, JSONObject response) {

    }

    /**
     * Returns when request succeeds
     *
     * @param statusCode http response status line
     * @param headers    response headers if any
     * @param response   parsed response if any
     */
    public void onSuccess(int statusCode, Header[] headers, JSONArray response) {

    }

    /**
     * Returns when request failed
     *
     * @param statusCode    http response status line
     * @param headers       response headers if any
     * @param throwable     throwable describing the way request failed
     * @param errorResponse parsed response if any
     */
    public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {

    }

    /**
     * Returns when request failed
     *
     * @param statusCode    http response status line
     * @param headers       response headers if any
     * @param throwable     throwable describing the way request failed
     * @param errorResponse parsed response if any
     */
    public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONArray errorResponse) {

    }

    @Override
    public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
        final AlertDialog.Builder dialog = new AlertDialog.Builder(AppManager.ActivityManager.current());
        dialog.setIcon(android.R.drawable.ic_dialog_info);
        dialog.setTitle(R.string.app_error);
        dialog.setMessage(responseString);
        dialog.setNegativeButton(R.string.sure,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
        dialog.show();
    }

    @Override
    public void onSuccess(int statusCode, Header[] headers, String responseString) {

    }

    @Override
    public final void onSuccess(final int statusCode, final Header[] headers, final byte[] responseBytes) {
        if (statusCode != HttpStatus.SC_NO_CONTENT) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        final Object jsonResponse = parseResponse(responseBytes);
                        postRunnable(new Runnable() {
                            @Override
                            public void run() {
                                if (jsonResponse instanceof JSONObject) {
                                    onSuccess(statusCode, headers, (JSONObject) jsonResponse);
                                } else if (jsonResponse instanceof JSONArray) {
                                    onSuccess(statusCode, headers, (JSONArray) jsonResponse);
                                } else if (jsonResponse instanceof String) {
                                    onFailure(statusCode, headers, (String) jsonResponse, new JSONException("Response cannot be parsed as JSON data"));
                                } else {
                                    onFailure(statusCode, headers, new JSONException("Unexpected response type " + jsonResponse.getClass().getName()), (JSONObject) null);
                                }

                            }
                        });
                    } catch (final JSONException ex) {
                        postRunnable(new Runnable() {
                            @Override
                            public void run() {
                                onFailure(statusCode, headers, ex, (JSONObject) null);
                            }
                        });
                    }
                }
            }).start();
        } else {
            onSuccess(statusCode, headers, new JSONObject());
        }
    }

    @Override
    public final void onFailure(final int statusCode, final Header[] headers, final byte[] responseBytes, final Throwable throwable) {
        if (responseBytes != null) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        final Object jsonResponse = parseResponse(responseBytes);
                        postRunnable(new Runnable() {
                            @Override
                            public void run() {
                                if (jsonResponse instanceof JSONObject) {
                                    onFailure(statusCode, headers, throwable, (JSONObject) jsonResponse);
                                } else if (jsonResponse instanceof JSONArray) {
                                    onFailure(statusCode, headers, throwable, (JSONArray) jsonResponse);
                                } else if (jsonResponse instanceof String) {
                                    onFailure(statusCode, headers, (String) jsonResponse, throwable);
                                } else {
                                    onFailure(statusCode, headers, new JSONException("Unexpected response type " + jsonResponse.getClass().getName()), (JSONObject) null);
                                }
                            }
                        });

                    } catch (final JSONException ex) {
                        postRunnable(new Runnable() {
                            @Override
                            public void run() {
                                onFailure(statusCode, headers, ex, (JSONObject) null);
                            }
                        });

                    }
                }
            }).start();
        } else {
            Log.v(LOG_TAG, "response body is null, calling onFailure(Throwable, JSONObject)");
            onFailure(statusCode, headers, throwable, (JSONObject) null);
        }
    }

    /**
     * Returns Object of type {@link JSONObject}, {@link JSONArray}, String, Boolean, Integer, Long,
     * Double or {@link JSONObject#NULL}, see {@link org.json.JSONTokener#nextValue()}
     *
     * @param responseBody response bytes to be assembled in String and parsed as JSON
     * @return Object parsedResponse
     * @throws org.json.JSONException exception if thrown while parsing JSON
     */
    protected Object parseResponse(byte[] responseBody) throws JSONException {
        if (null == responseBody)
            return null;
        Object result = null;
        //trim the string to prevent start with blank, and test if the string is valid JSON, because the parser don't do this :(. If Json is not valid this will return null
        String jsonString = getResponseString(responseBody, getCharset());
        if (jsonString != null) {
            jsonString = jsonString.trim();
            if (jsonString.startsWith("{") || jsonString.startsWith("[")) {
                result = new JSONTokener(jsonString).nextValue();
            }
        }
        if (result == null) {
            result = jsonString;
        }
        return result;
    }

    /**
     * Attempts to encode response bytes as string of set encoding
     *
     * @param charset     charset to create string with
     * @param stringBytes response bytes
     * @return String of set encoding or null
     */
    public static String getResponseString(byte[] stringBytes, String charset) {
        try {
            return stringBytes == null ? null : new String(stringBytes, charset);
        } catch (UnsupportedEncodingException e) {
            Log.e(LOG_TAG, "Encoding response into string failed", e);
            return null;
        }
    }
}

现在如果再出现 HTTP 500 或其他服务端错误(输出非 JSON 字符串)时将会直接弹出服务端页面内容的对话框方便调试了,现在只能这样了,等新版本发布后再转换下吧!





目录
相关文章
|
5月前
|
Serverless
函数计算在执行请求的过程中遇到了意外的错误
函数计算在执行请求的过程中遇到了意外的错误
62 1
|
7月前
|
Go 数据库
sync.Once-保证运行期间的某段代码只会执行一次
sync.Once-保证运行期间的某段代码只会执行一次
40 0
|
4月前
|
编译器
【报错】错误 C1004 :发现意外的文件尾
【报错】错误 C1004 :发现意外的文件尾
76 0
|
5月前
|
SQL 关系型数据库 数据库
记一次程序 Bug 导致数据删除的恢复过程
使用RDS、DMS进行数据恢复实践
949 0
|
存储 Web App开发 JSON
检查自己的代码是否存在内存泄露
造成内存泄露的根本原因就是我们写的代码中存在某些对象长期占用内存,得不到释放,且这个对象占用的内存会逐步增加,导致 v8 无法回收,从而造成的服务的异常和不稳定,甚至是服务的中断和崩溃。
249 0
检查自己的代码是否存在内存泄露
关于 qt程序退出出现“已停止工作”程序奔溃问题 的解决方法
关于 qt程序退出出现“已停止工作”程序奔溃问题 的解决方法
关于 qt程序退出出现“已停止工作”程序奔溃问题 的解决方法
R代码忘记保存,系统崩溃了怎么办?
跑程序时电脑突然崩溃,程序被强制中断导致代码不见了怎么办? 这些糟心的情况想必每个打工人都不想经历,偏偏我就是那个倒霉蛋,今早打开电脑发现昨晚写的代码忘记保存,心态崩到想当场飙眼泪,冷静下来之后开始寻找解决方案
1172 0
R代码忘记保存,系统崩溃了怎么办?
|
安全 Java Apache
Log4j 漏洞修复和临时补救方法
Log4j 漏洞修复和临时补救方法
801 0
|
程序员 Shell
如何重复执行一条命令直至运行成功?
大家好,我是良许。 在我们的日常工作中,需要我们重复做的工作简直不能太多。比如,我们想要确认网络是否是连通的,传统的做法就是使用 ping 命令不停去测试某个地址(比如百度)。网络比较好还好说,但如果网络很差,那么就需要一直去运行 ping 命令。 作为程序员,重复性的工作怎么能忍呢?只要是重复性的工作,就有可能使用编程的方式来解决! 下面良许就介绍两种方法重复执行一条命令直至运行成功。 (PS:本文适合初学者,高手可绕道) 解决重复性的工作,自然而然会想到循环 。在 Shell 里,循环无非 3 种:for、while、until 。在本文里,我们使用后两种循环:while 、un
159 0