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. 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).
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.
Currently my extended AsyncTask class has these parameters: String, Void, JSONObject and the following code is what I have in my doInBackground method.
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. 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.
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.
So how do I go about handling response errors when my method returns a JSONObject?
200 OK or 201 Created are the best choice for a successful POST request.
HTTP status codes and the error message can give you a clue. In general, a 5xx status code can be retried, a 4xx status code should be checked first, and a 3xx or 2xx code does not need retried.
The 5xx series of status codes is for representing problems on the server side. In most cases, these codes mean the server is not in a state to run the client's request or even see whether it's correct, and that the client should retry its request later.
You have a couple options (I say #1 is your best bet)
1) Create a custom JSON object to carry the statuscode from the background part to the UI (or other calling thread). Then just check if the JSON returned from the asynctask is one of the 'HTTP result JSONs' instead of whatever the normal results are. (essentially wrap your 'exceptions'/etc. from the background processing in JSON and use JSON to transport your return message for processing in either condition.)
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)
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.)
4) you can do like https://stackoverflow.com/a/6312491/5673694 says to do. But there is 1 bad issue and 1 'ehh' issue...
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. 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. (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
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With