繁体   English   中英

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

[英]How should I handle HTTP response codes when using AsyncTask?

我正在创建一个接受用户输入的android应用,尝试使用指定的输入连接到API网址,并检索数据并显示它。 现在,我已经能够执行上述所有操作,但是有一个潜在的机会,如果用户输入了某些内容而又不存在,我的应用程序将由于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.";
}

我无法返回字符串,因为我的AsyncTask参数返回了JSONObject。 我可以对其进行更改,以便它确实返回String,但是我认为这不是处理响应错误的正确逻辑方法。

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

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

您有几种选择(我说#1是您最好的选择)

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

2)您可以引发异常(但我个人认为这是不好的设计,通常更好地捕获异常,然后在onPostExecute()中处理它们(通过#1这样的标志)

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

4)您可以按照https://stackoverflow.com/a/6312491/5673694的说明进行操作。 但是有1个不良问题和1个“ ehh”问题...

不好的问题:她的实现存在内存泄漏问题。 Java中的内部类在实例化时对其外部类实例具有继承引用。 这意味着,如果您的异步任务仍在运行,并且由于某种原因您退出了应用程序/打进了电话等,则您的父类/(最有可能的活动)将无法被垃圾回收。因此,您的应用程序应该在很长时间内不占用系统内存。 (多长时间(无限可能地)运行asyncTask)要解决此问题,请将内部类设为静态,然后对类实例使用WeakRefernce <>。 (这应该在Android中处理后台任务的所有内部类(例如Handlers等)中完成。)此内存泄漏问题没有得到充分记录,但存在,我们在MOOC中讨论,我的博士顾问是我是讲师https://www.coursera.org/course/posacommunication

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

当statusCode不是200时,可以返回null:

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

            int statusCode = urlConnection.getResponseCode();

            if(statusCode!= 200){

                return null;

            }

然后在您的postExecute中可以检查该条件:

protected void onPostExecute(JSONObject result) {

    if (result == null) {

        // Inform the user something weird happened

    }
    else{

        // Do your normal condition with your JSON object
    }

您还可以尝试另一种方法:您可以返回ArrayList而不是返回JSON对象:

            ArrayList<Object>  result = new ArrayList<Object>();

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

            int statusCode = urlConnection.getResponseCode();


            switch (statusCode) {

                case 200:
                   // Your code to build your JSON object
                   JSONObject yourJsonObject = ...
                   result.add("Ok");
                   result.add(yourJsonObject);
                   break;
                case 400:
                   result.add("Error 400 - Bad request.");
                   result.add(null);
                   break;
                case 401:
                   result.add("Error 401 - Unauthorized request.");
                   result.add(null);
                   break;
            }

然后在您的postExecute中检查该ArrayList对象:

protected void onPostExecute(ArrayList<Object> result) {

    String message = (String) result.get(0);
    JSONObject yourJsonObject = (JSONObject) result.get(1);


    if (result == yourJsonObject) {

        // Inform the user something weird happened
        // Example: Toast the message

    }
    else{

        // Do your normal condition with your JSON object

    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM