Reputation: 795
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 ?
Upvotes: 2
Views: 20611
Reputation: 2560
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.
Upvotes: 2
Reputation: 2962
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
}
});
Upvotes: 1
Reputation: 9295
I suggest using android-async-http ( http://loopj.com/android-async-http/ ) library. It makes android async http calls simple and elegant.
Upvotes: 3
Reputation: 1753
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:
Upvotes: 5
Reputation:
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
Upvotes: 2