user934779
user934779

Reputation: 303

Android: Issue with JSON in AsyncTask

I have a JSON file (towns.json) sitting on my server and in my app I want the data to be read from there. So I figured out I should use the AsyncTask to not block the UI thread. I am doing it as follows:

    private class GetTowns extends AsyncTask<String, String, Void> {
    protected void onPreExecute() {}

    @Override
    protected Void doInBackground(String... params) {
        String readTown = readFeed(ScreenStart.this, "http://server.com/towns.json");
        try {
            JSONArray jsonArray = new JSONArray(readTown);
            town = new ObjectTown[jsonArray.length()];
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                town[i] = new ObjectTown();
                town[i].setId(Integer.parseInt(jsonObject.getString("id")));
                town[i].setName(jsonObject.getString("name"));
                town[i].setLat(Double.parseDouble(jsonObject.getString("latitude")));
                town[i].setLon(Double.parseDouble(jsonObject.getString("longitude")));
            }
        } catch (Exception e) {
            Log.i("Catch the exception", e + "");
        }
        return null;
    }

    protected void onPostExecute(Void v) {}
}

And the readFeed() function here:

public static String readFeed(Context context, String str) {
    StringBuilder builder = new StringBuilder();
    HttpClient client = new DefaultHttpClient();
    HttpGet httpGet = new HttpGet(str);

    try {
        HttpResponse response = client.execute(httpGet);

        StatusLine statusLine = response.getStatusLine();
        int statusCode = statusLine.getStatusCode();
        if (statusCode == 200) {
            HttpEntity entity = response.getEntity();
            InputStream content = entity.getContent();
            BufferedReader reader = new BufferedReader(new InputStreamReader(content, "ISO-8859-1"));
            String line;
            while ((line = reader.readLine()) != null) {
                builder.append(line);
            }
        } 
    } catch (Exception e) {
        e.printStackTrace();
    }
    return builder.toString();
}

It works sometimes... but once in a while, the doInBackground() throws this exception:

org.json.JSONException: End of input at character 0 of...

What exactly am I doing wrong?

Upvotes: 0

Views: 821

Answers (2)

Snicolas
Snicolas

Reputation: 38168

It is not a good idea to use AsyncTasks to send REST requests. AsyncTasks should not be used for long running operations such as networking. Indeed AsyncTask have two main issues that are related :

  • they are poorly tied to the activity life cycle
  • the create memory leaks very easily.

Inside the RoboSpice Motivations app (available on Google Play) we give an in-depth view of AsyncTasks, Loaders, their features and drawbacks when it comes to networking and also introduce you to an alternative solution : RoboSpice.

We even provided an infographics to explain this issue. To put it in a few words

  • AsyncTasks are flawed as they are poorly tied to Activity Lifecycle and create memory leaks
  • Loaders are pretty good for what they have been designed for : accessing cursors of Sqlite databases, but don't offer any support for networking. They are the wrong tool for this.
  • RoboSpice executes network requests in a service, your downloads are executed in an Android Service, memory is well managed and it even provides support for writing REST requests.

I encourage you to download the RoboSpice Motivations app, it really explains this in-depth and provides samples and demonstrations of the different ways to do some background operations.

Upvotes: 1

marcinj
marcinj

Reputation: 49976

It looks like server is not returning data, have you checked it your string is non empty?. To turn HttpEntity into string you can use:

String jsonStr = EntityUtils.toString(httpEntity);

I suppose you should also check if entity is different from null before using it.

Upvotes: 1

Related Questions