使用AsyncTask时应该如何处理HTTP响应代码?

Tem*_*tex 6 java android android-asynctask

我正在创建一个Android应用程序,它接受用户输入,尝试使用指定的输入建立与API URL的连接并检索数据并显示它.现在我已经能够完成上述所有工作,但是如果用户输入某些内容并且它不存在,我的应用程序可能会因为NPE(空指针异常)而崩溃.

我正在使用的API向我显示了可能发生的响应错误列表,但我不确定如何处理或实现将这些响应错误考虑在内的功能.

目前我的扩展AsyncTask类有以下参数:String,Void,JSONObject和以下代码是我在doInBackground方法中的代码.

URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();

int statusCode = urlConnection.getResponseCode();
switch (statusCode) {
    case 400:
    return "Error 400 - Bad request.";
    case 401:
    return "Error 401 - Unauthorized request.";
}
Run Code Online (Sandbox Code Playgroud)

我无法返回一个String,因为我的AsyncTask参数返回一个JSONObject.我可以改变它,所以它确实返回一个字符串,但我认为这不是处理响应错误的正确逻辑方式.

现在,如果API响应代码是404(找不到数据),我不希望应用程序崩溃,因为它无法返回JSONObject,而是我希望它继续下一个片段并显示最少的信息.

那么当我的方法返回JSONObject时,如何处理响应错误呢?

maw*_*ker 2

你有几个选择(我说#1是你最好的选择)

1) 创建一个自定义 JSON 对象,将状态码从后台部分传送到 UI(或其他调用线程)。然后只需检查从 asynctask 返回的 JSON 是否是“HTTP 结果 JSON”之一,而不是正常结果。(本质上将后台处理中的“异常”/等包装在 JSON 中,并使用 JSON 传输返回消息以在任一条件下进行处理。)

2)你可以抛出异常(但我个人认为这是糟糕的设计,通常最好捕获异常然后在 onPostExecute() 中处理它们(通过像#1这样的标志)

3)您可以在 asyncTask 之外的某个位置设置一个标志来确定返回代码是什么(但这通常不是线程安全的。这意味着如果您的用户导致两个任务同时运行并且它们以不同的顺序返回,这可能会很麻烦(或同时),您可能无法获得每个回报的“正确”值。)

4)你可以像/sf/answers/441874401/所说的那样做。但有 1 个坏问题和 1 个“呃”问题......

糟糕的问题:她的实现存在内存泄漏问题。Java 中的内部类在实例化时具有对其外部类实例的继承引用。这意味着,如果您的异步任务仍在运行,那么您的父类/(最有可能的活动)将无法被垃圾收集,如果您出于某种原因退出您的应用程序/接到电话/等等...因此,您的应用程序可能会在很长一段时间内耗尽系统内存。(无论你的 asyncTask 运行多久(无限可能))要解决此问题,请将内部类设为静态,并对类实例使用 Wea​​kRefernce<>。(这应该对 Android 中处理后台任务的所有内部类进行,例如处理程序等。)这个内存泄漏问题没有得到很好的记录,但确实存在,我们在 MOOC 中讨论了这个问题,我的博士导师是讲师和我是工作人员https://www.coursera.org/course/posacommunication

“呃”问题(这更像是一个“被警告”问题)...您可以让 AsyncTask 存储异常,但是如果您在 AsyncTask 类中将其设为静态,则可能会导致问题(Java 中的静态和泛型与 C++ 中的工作方式不同,在 C++ 中,模板类的每个变体都有不同的类实现,但在 Java 中只有 1 个类文件,因此静态是“共享”的所有不同版本之间。)(注意:上面说的是“静态类”,这里我谈论的是“该类中的静态变量”)