Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the most efficient way on Android to call HTTP Web API calls that return a JSON response?

I'm the perfectionist type, I already got web API calls working fine with Google Places API (just as an example), but I feel it's sometimes slow or maybe I'm not doing it right. Some blogs are saying I should use AndroidHttpClient, but I'm not, should I ?

The web API calls i'm using return json and I don't run them on the UI thread, hence using AsyncTask (is AsyncTask the most efficient way to run on background thread or should I use something else ?)

Please see my code and tell me how could it be more efficient in anyway

public static class NearbySearchRequest extends AsyncTask<String, Void, JSONObject> {     Exception mException = null;      @Override     protected void onPreExecute()     {         super.onPreExecute();         this.mException = null;     }      @Override     protected JSONObject doInBackground(String... params)     {         StringBuilder urlString = new StringBuilder();         urlString.append("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");         urlString.append("key=").append(Constants.GOOGLE_SIMPLE_API_KEY);         urlString.append("&location=").append(params[0]);         urlString.append("&sensor=").append("true");         urlString.append("&language=").append("en-GB");         urlString.append("&name=").append(params[1]);         urlString.append("&rankby=").append("distance");          LogHelper.Log(urlString.toString());          HttpURLConnection urlConnection = null;         URL url = null;         JSONObject object = null;          try         {             url = new URL(urlString.toString());             urlConnection = (HttpURLConnection) url.openConnection();             urlConnection.setRequestMethod("GET");             urlConnection.setDoOutput(true);             urlConnection.setDoInput(true);             urlConnection.connect();             InputStream inStream = null;             inStream = urlConnection.getInputStream();             BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));             String temp, response = "";             while ((temp = bReader.readLine()) != null)                 response += temp;             bReader.close();             inStream.close();             urlConnection.disconnect();             object = (JSONObject) new JSONTokener(response).nextValue();         }         catch (Exception e)         {             this.mException = e;         }          return (object);     }      @Override     protected void onPostExecute(JSONObject result)     {         super.onPostExecute(result);          if (this.mException != null)             ErrorHelper.report(this.mException, "Error # NearbySearchRequest");     } } 
like image 398
Mohamed Heiba Avatar asked Sep 27 '13 12:09

Mohamed Heiba


People also ask

Is REST API always JSON?

REST APIs should accept JSON for request payload and also send responses to JSON. JSON is the standard for transferring data. Almost every networked technology can use it: JavaScript has built-in methods to encode and decode JSON either through the Fetch API or another HTTP client.

What will you use to call an API from a browser?

You can use any HTTP client to invoke your web API. In fact, you can invoke it directly from a web browser. In Visual Studio, start your application in debugging mode. Visual Studio will automatically open a web browser window with URL that points to http://localhost<portnumber>.

Why API calls take so long?

The larger the database (more data concerning devices, users, etc.), the longer it will take to sort through all the data and return a result. This also correlates to the back-end where calls are processed on a server.

What is a successful API call?

200 OK: The request was successful. 201 Created: The resource has been created on the server. This response is typically returned for POST requests. 202 Accepted: The request has been received but is still being processed. 204 No Content: The request has been successfully processed but no content will be returned.


1 Answers

The Http engine you're using seems the best choice. Actually any other 3-rd party engines are based either on Apache, either on HttpUrlConnection. I prefer to use Spring for Android as that API provide an abstraction over Http Engine and you don't really need to care how about what API to use based on API level. Or you can use Volley - a very fashionable library.

I would touch however some of your code:

  1. What if there is an exception while reading the stream? Then the stream remains open and also the connection. So I would suggest to have a finally block where the streams and connection is closed no matter if you get an exception or not:

    HttpURLConnection urlConnection = null; URL url = null; JSONObject object = null; InputStream inStream = null; try {     url = new URL(urlString.toString());     urlConnection = (HttpURLConnection) url.openConnection();     urlConnection.setRequestMethod("GET");     urlConnection.setDoOutput(true);     urlConnection.setDoInput(true);     urlConnection.connect();     inStream = urlConnection.getInputStream();     BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));     String temp, response = "";     while ((temp = bReader.readLine()) != null) {         response += temp;     }     object = (JSONObject) new JSONTokener(response).nextValue(); } catch (Exception e) {     this.mException = e; } finally {     if (inStream != null) {         try {             // this will close the bReader as well             inStream.close();         } catch (IOException ignored) {         }     }     if (urlConnection != null) {         urlConnection.disconnect();     } } 
  2. JSON parsing: you're using the Android standard way of parsing JSON, but that's not the fastest and easiest to work with. GSON and Jackson are better to use. To make a comparison when it comes for JSON parsers, I would go for Jackson. Here's another SO topic on this comparison.

  3. Don't concatenate strings like that as concatenating strings will create each time another string. Use a StringBuilder instead.

  4. Exception handling (this is anyway a long-debate subject in all programming forums). First of all you have to log it (Use Log class not System.out.printXXX). Then you need to either inform the user: either you toast a message, either you show a label or notification. The decision depends on the user case and how relevant is the call you're making.

These are the topics I see in you code.

EDIT I realize I didn't answer this: is AsyncTask the most efficient way to run on background thread or should I use something else?

The short answer I would give is: if you're supposed to perform a short time lived request, then AsyncTask is perfect. However, if you need to get some data and display it - but you don't want to worry about whether to download again if the screen is rotated and so on, I would strongly recommend using an AsyncTaskLoader and Loaders in general.

If you need to download some big data, then either you use an IntentService or, for heavy-weight operations, DownloadManager.

Enjoy coding!

like image 105
gunar Avatar answered Sep 20 '22 10:09

gunar