简体   繁体   English

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

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

I am creating an android app which takes user input, attempts to make a connection to the API url with the specified input and retrieve data and display it. 我正在创建一个接受用户输入的android应用,尝试使用指定的输入连接到API网址,并检索数据并显示它。 Now I've been able to do everything above but there is a potential chance that if a user enters something and it doesn't exist my app will crash because of a NPE (Null Pointer Exception). 现在,我已经能够执行上述所有操作,但是有一个潜在的机会,如果用户输入了某些内容而又不存在,我的应用程序将由于NPE(空指针异常)而崩溃。

The API I am using shows me a list of response errors that can occur but I'm not sure how I should handle or implement a feature that takes these response errors into account. 我正在使用的API向我显示了可能发生的响应错误的列表,但是我不确定如何处理或实现将这些响应错误考虑在内的功能。

Currently my extended AsyncTask class has these parameters: String, Void, JSONObject and the following code is what I have in my doInBackground method. 当前,我的扩展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.";
}

I can't return a String because my AsyncTask param returns a JSONObject. 我无法返回字符串,因为我的AsyncTask参数返回了JSONObject。 I can change it so it does return a String but I believe it's not the proper logical way of handling the response errors. 我可以对其进行更改,以便它确实返回String,但是我认为这不是处理响应错误的正确逻辑方法。

Now if the API response code was a 404 (No data found), I don't want the app to crash because it can't return the JSONObject, instead I would like it to continue on to the next fragment and display minimal information. 现在,如果API响应代码为404(未找到数据),我不希望该应用程序崩溃,因为它无法返回JSONObject,而是希望它继续进行下一个片段并显示最少的信息。

So how do I go about handling response errors when my method returns a JSONObject? 那么,当我的方法返回JSONObject时,如何处理响应错误?

You have a couple options (I say #1 is your best bet) 您有几种选择(我说#1是您最好的选择)

1) Create a custom JSON object to carry the statuscode from the background part to the UI (or other calling thread). 1)创建一个自定义JSON对象,以将状态代码从后台部分传送到UI(或其他调用线程)。 Then just check if the JSON returned from the asynctask is one of the 'HTTP result JSONs' instead of whatever the normal results are. 然后只要检查从asynctask返回的JSON是否是“ HTTP结果JSON”之一,而不是正常结果即可。 (essentially wrap your 'exceptions'/etc. from the background processing in JSON and use JSON to transport your return message for processing in either condition.) (本质上是将您的“ exceptions” /等内容从JSON中的后台处理包装起来,并使用JSON来传输您的返回消息以在任何一种情况下进行处理。)

2) You can throw an exception (but personally I think this is bad design, Its generally better to catch exceptions and then handle them in the onPostExecute() (Via flags like #1) 2)您可以引发异常(但我个人认为这是不好的设计,通常更好地捕获异常,然后在onPostExecute()中处理它们(通过#1这样的标志)

3) You can set a flag somewhere outside the asyncTask as to what the return code was (But this is generally NOT thread safe. Meaning it might be troublesome if your user causes two tasks to be ran at once and they return in different order (or at same time) and you might not get the 'right' value for each's return.) 3)您可以在asyncTask外部的某个位置设置一个关于返回代码的标志(但这通常不是线程安全的。这意味着如果您的用户导致一次运行两个任务并且它们以不同的顺序返回,这可能会很麻烦(或同时),则您可能无法获得每次回报的“正确”值。)

4) you can do like https://stackoverflow.com/a/6312491/5673694 says to do. 4)您可以按照https://stackoverflow.com/a/6312491/5673694的说明进行操作。 But there is 1 bad issue and 1 'ehh' issue... 但是有1个不良问题和1个“ ehh”问题...

The bad issue: Her implementation HAS A MEMORY LEAK issue with it. 不好的问题:她的实现存在内存泄漏问题。 Inner classes in Java have an inherit reference to their outer class instance when they are instantiated. Java中的内部类在实例化时对其外部类实例具有继承引用。 This means that if your async task is still running that your parent class/(activity most likely) won't be able to be Garbage Collected if you for some reason back out of your application/a phone call comes in/etc... So your Application can eat up memory from the system when it shouldn't for quite a long time. 这意味着,如果您的异步任务仍在运行,并且由于某种原因您退出了应用程序/打进了电话等,则您的父类/(最有可能的活动)将无法被垃圾回收。因此,您的应用程序应该在很长时间内不占用系统内存。 (however long your asyncTask runs(infinitely possibly)) To fix this, make the inner class static, and use a WeakRefernce<> to the Class Instance. (多长时间(无限可能地)运行asyncTask)要解决此问题,请将内部类设为静态,然后对类实例使用WeakRefernce <>。 (This should be done for ALL inner classes in Android where they work with background tasks, such as Handlers, etc.) This Memory Leak issue isn't well documented, but exists and we discuss it in the MOOC that my PhD adviser is the Instructor and I'm Staff https://www.coursera.org/course/posacommunication (这应该在Android中处理后台任务的所有内部类(例如Handlers等)中完成。)此内存泄漏问题没有得到充分记录,但存在,我们在MOOC中讨论,我的博士顾问是我是讲师https://www.coursera.org/course/posacommunication

the 'ehh' issue(And this is more of a 'be warned' issue)... you can make the AsyncTask store the Exception, but this has the problem of potentially causing problems if you ever make it a static in your AsyncTask class (Statics and Generics in Java don't work the same way as they do in C++, in C++ you get different class implementations for each variation of a templated class, but in Java there is only 1 class file so therefore statics are 'shared' between all different versions.) (Note: just above says 'static class' and here I'm talking about 'static variables within that class') “ ehh”问题(这更多是“被警告”的问题)...您可以使AsyncTask存储Exception,但是如果您在AsyncTask类中将其设置为静态的,则可能会引起问题(Java中的静态和泛型工作方式与C ++中的不同,在C ++中,对于模板化类的每个变体,您都有不同的类实现,但是在Java中只有1个类文件,因此静态是“共享的”在所有不同版本之间。)(注意:上面说的是“静态类”,这里我说的是“该类中的静态变量”)

You can return null when the statusCode is not 200: 当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;

            }

Then in your postExecute you can check that condition: 然后在您的postExecute中可以检查该条件:

protected void onPostExecute(JSONObject result) {

    if (result == null) {

        // Inform the user something weird happened

    }
    else{

        // Do your normal condition with your JSON object
    }

You can also try another approach: instead of returning a JSON object, you can return a ArrayList: 您还可以尝试另一种方法:您可以返回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;
            }

And then in your postExecute check that ArrayList object: 然后在您的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.

相关问题 如何使用AsyncTask读取HTTP响应? - How to read HTTP response using AsyncTask? 如何在Axis 1客户端中处理HTTP错误代码 - How do I handle HTTP error codes in an Axis 1 client 使用SwingWorker时如何处理异常? - How should I handle exceptions when using SwingWorker? 如何处理具有许多无效URL的代理HTTP请求 - How should I handle proxying HTTP requests with many invalid URLs 从jersey返回HTTP代码出错时的Chunked响应 - Return HTTP codes from jersey Chunked response when in error CXF客户端代理如何处理客户端内的某些响应代码 - CXF client proxy how to handle certain response codes within the client 如何正确处理网络状态和HTTP状态代码 - How to handle network state and HTTP status codes correctly 使用Wicket表单时,如何更好地处理Wicket模型的加载? - How should I better handle loading of Wicket Models when using Wicket forms? 使用 Netty 的 LengthFieldBasedFrameDecoder 时我应该如何处理 ASCII 值? - How should I handle an ASCII value when using Netty's LengthFieldBasedFrameDecoder? 在jersey中使用streamoutput响应时,如何在我已经刷新一些输出后处理异常? - When using streamoutput response in jersey,how to handle exception after I already flush some output?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM