from:http://blog.androgames.net/12/retrieving-data-asynchronously/
In Android, the system guards against applications that are insufficiently responsive for a period of time by displaying a dialog to the user, called the Application Not Responding (ANR) dialog. The user can choose to let the application continue, but the user won’t appreciate having this dialog displayed every time he or she uses your application . So it’s important to design responsiveness into your application, so that the system never has cause to display an ANR to the user.
In this tutorial we are going to see how to perform asynchronous request to distant servers using the build’in HTTPClient without blocking the UI thread. the problem is that we have no possibilities to control the distant server responsiveness and the user Internet connection speed wich can cause the server’s response to be received after several seconds…
The problem we want to solve is quite simple. Running an Activity, we want to fetch data from a distant server and process it without blocking the UI thread.
The Activity will react to a user action and send data to a distant server. The distant server will send back raw data to the application wich will produce processed data. The running Activity can then display the processed data to the user.
We need :
Our Activity will send data to the distant server with a static call on our client passing the request to send to the server and the callback listener to recieve the processed data.
Client.sendRequest(request, this);
A static method from our client will start a new AsynchronousSender in a new Thread
import android.os.Handler; import org.apache.http.HttpRequest; public class Client { public static void sendRequest(final HttpRequest request, ResponseListener callback) { (new AsynchronousSender(request, new Handler(), new CallbackWrapper(callback))).start(); } }
The running Activity must implemment the ResponseListener interface to recieve the processed data from the server.
import org.apache.http.HttpResponse; public interface ResponseListener { public void onResponseReceived(HttpResponse response); }
Finaly, the AsynchronousSender will send the request to the distant server and process the server’s response before passing the processed data back to the specified ResponseListener.
import java.io.IOException; import org.apache.http.HttpResponse; import org.apache.http.HttpRequest; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.impl.client.DefaultHttpClient; import android.os.Handler; public class AsynchronousSender extends Thread { private static final DefaultHttpClient httpClient = new DefaultHttpClient(); private Request request; private Handler handler; private CallbackWrapper wrapper; protected AsynchronousSender(HttpRequest request, Handler handler, CallbackWrapper wrapper) { this.request = request; this.handler = handler; this.wrapper = wrapper; } public void run() { try { final HttpResponse response; synchronized (httpClient) { response = getClient().execute(request); } // process response wrapper.setResponse(response); handler.post(wrapper); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private HttpClient getClient() { return httpClient; } }
We use a CallbackWrapper to send the processed data back to the Activity as the Hander needs a Runnable to post.
import org.apache.http.HttpResponse; public class CallbackWrapper implements Runnable { private ResponseListener callbackActivity; private HttpResponse response; public CallbackWrapper(ResponseListener callbackActivity) { this.callbackActivity = callbackActivity; } public void run() { callbackActivity.onResponseReceived(response); } public void setResponse(HttpResponse response) { this.response = response; } }