2

I am using an application where i just need to download a pair of coordinates for google maps from a mysql server. I can do this successfully using php and a normal httpost but my app freezes for a few seconds when i do it.

I read that you need to make httppost asycronous in order to avoid that freezing until the server finishes the prossess and sends the results.

The point is that i need that results in a json array like the normal httpost.

For example if i had this httppost.

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");

try {
    // Add your data
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
    nameValuePairs.add(new BasicNameValuePair("id", "12345"));
    nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
    httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    // Execute HTTP Post Request
    HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
} catch (IOException e) {
    // TODO Auto-generated catch block
}

String result11 = null;
// convert response to string
try {
    BufferedReader reader = new BufferedReader(new InputStreamReader(is11, "iso-8859-1"), 8);
    StringBuilder sb = new StringBuilder();
    sb.append(reader.readLine() + "\n");
    String line = "0";
    while ((line = reader.readLine()) != null) {
        sb.append(line + "\n");
    }
    is11.close();
    result11 = sb.toString();
} catch (Exception e) {
    Log.e("log_tag", "Error converting result " + e.toString());
}

// parsing data
try {
    JSONArray jArray1 = new JSONArray(result11);
} catch (JSONException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

How can i convert that to an asynchronous post so i can avoid the freeze ?

1
  • I have no idea how your code could even compile as it is, but please use EntityUtils.toString(response.getEntity()) instead of having your own BufferedReader-n-StringBuilder party. The former is less code, has correct error handling and obeys the character encoding sent by the server. Commented Mar 31, 2012 at 9:27

5 Answers 5

5

There is a nice class AsyncTask which can be used to easily run asynchronous tasks. If you embed your code in such a subclass, you might end up with this:

public class FetchTask extends AsyncTask<Void, Void, JSONArray> {
    @Override
    protected JSONArray doInBackground(Void... params) {
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");

            // Add your data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("id", "12345"));
            nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            // Execute HTTP Post Request
            HttpResponse response = httpclient.execute(httppost);

            BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            sb.append(reader.readLine() + "\n");
            String line = "0";
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
            reader.close();
            String result11 = sb.toString();

            // parsing data
            return new JSONArray(result11);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    @Override
    protected void onPostExecute(JSONArray result) {
        if (result != null) {
            // do something
        } else {
            // error occured
        }
    }
}

You can start the task using:

new FetchTask().execute();

Additional resources:

Sign up to request clarification or add additional context in comments.

Comments

3

I suggest using android-async-http ( http://loopj.com/android-async-http/ ) library. It makes android async http calls simple and elegant.

2 Comments

unfortunately there are only few demos available that make it easier for a newbie to understand how to put everything together, like in this case to post data to an URL and to process a response utilizing JSON. I understand it's all there and seems to be very powerful and smart, but a few more examples would definitely help.
I've used it and found it easy to start with. I started with the code sample given in "Recommended Usage" section in loopj.com/android-async-http. I'd learn and do certain things along the way, such as persisting the cookies, making it work with SSL (trusted and untrusted), adding a check to see if the device is online or not etc. I feel all of these issues will have to be dealt with whether you use this library or Android API.
2

Rather than just starting a new thread, it's a better idea to go with a full-fledged AsyncTask. It provides much greater control of things.

private class DoPostRequestAsync extends AsyncTask<URL, Void, String> {
     protected String doInBackground(URL url) {
        //Your download code here; work with the url parameter and then return the result
        //which if I remember correctly from your code, is a string.
        //This gets called and runs ON ANOTHER thread
     }

     protected void onPostExecute(String result) {
         //This gets called on the interface (main) thread!
         showDialog("Done! " + result);
     }
 }

Place the new class implementation inside of your desired Activity's class. For more info on AsyncTask please follow this link:

http://developer.android.com/reference/android/os/AsyncTask.html

Comments

2

Assuming you want to do this on a button click:

public void onClick(View v) {
  new Thread(new Runnable() {
        public void run() {
            //your code here
        }
    }).start();
}

Basically, you are putting IO intensive operation in a separate thread (not your UI thread) so that the UI does not freeze.

1 Comment

trying in a while and ill answer you. Thanks a lot for your response :)
1

Use an async http library like ion. https://github.com/koush/ion

All the threading and asynchronous boilerplate will be handled for you.

This is your same code, asynchronous, using Ion. Much simpler:

Ion.with(context)
.load("http://www.yoursite.com/script.php")
.setBodyParameter("id", "12345")
.setBodyParameter("stringdata", "AndDev is Cool!")
.asJsonArray()
.setCallback(new FutureCallback<JsonArray> {
  void onCompleted(Exception e, JsonArray result) {
    // do something with the result/exception
  }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.