Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to execute web request in its own thread?

I am creating an android application which has to execute web requests in the background and then handle the received data and modify the user interface according to the server response.

The goal of posting requests and handling data in the background is to avoid the freezing of user interface. Currently however I notice that the user interface is freezing so I am not sure the logic is working as it is supposed to.

Here is the part of code which is supposed to post requests and handle responses in its own thread and then pass the data to GUI:

public class ServerConnection {

Queue<String> requests;

...

DefaultHttpClient httpClient;
HttpHost targetHost;

Handler handler;

ServerResponseHandler responseHandler;
Activity activity;

public ServerConnection(Activity activity){
    this.activity = activity;
    this.responseHandler = (ServerResponseHandler) activity;
    httpClient = new DefaultHttpClient();
    targetHost = new HttpHost(TARGET_DOMAIN, 80, "http");
    requests = new LinkedList<String>();
}



private Runnable requestSender = new Runnable(){

    @Override
    public void run() {
        if(!requests.isEmpty()){
            String requestString = requests.remove();
            HttpGet httpGet = new HttpGet(requestString);
            httpGet.addHeader("Accept", "text/xml");
            String encodingString = "testuser:testpass";
            String sEncodedString = Base64Coder.encodeString(encodingString);

            try{

                String sContent = fetchURL(requestString, sEncodedString);

                XMLParser xmlParser = new XMLParser();

                List <Product> products = xmlParser.getProducts(sContent);

                responseHandler.onProductsResponse(products);
            }
            catch(Exception ex){
                Log.e(TAG, ex.getMessage());
            }
        }
    }
};

public void sendRequest(String requestString){
    requests.add(requestString);
    handler = new Handler();
    handler.post(requestSender);
}

The method sendRequest() is called from the main activity which implements ServerResponseHandler. I guess the request is executed in its own thread and by calling

responseHandler.onProductsResponse(products);

the list of products (data from the web) is passed to main activity. Anyway due to poor performance I would appreciate if anyone could correct any possible issue in the logic above or suggest any other (better) option.

like image 479
Niko Gamulin Avatar asked Jan 07 '10 17:01

Niko Gamulin


1 Answers

I'd suggest you take a look at ASyncTask class (available since Android 1.5).

It simplifies the process of creating a background Thread that synchronizes with the GUI thread once it's complete.

You should be able to achieve what you're trying using code something list this

private class DownloadFilesTask extends AsyncTask<String, List<Product>, Integer> {
     protected List<Products> doInBackground(String... requestStrings) {
        int count = requestStrings.length;
        int results = 0;
        for (int i = 0; i < count; i++) {
          String requestString = requestStrings[i];
          HttpGet httpGet = new HttpGet(requestString);
          httpGet.addHeader("Accept", "text/xml");
          String encodingString = "testuser:testpass";
          String sEncodedString = Base64Coder.encodeString(encodingString);
          try{
            String sContent = fetchURL(requestString, sEncodedString);
            XMLParser xmlParser = new XMLParser();
            List <Product> products = xmlParser.getProducts(sContent);
            results++;
            publishProgress(products);
          }
          catch(Exception ex){
            Log.e(TAG, ex.getMessage());
          }
        }
        return results;
     }

     protected void onProgressUpdate(Integer... progress) {
         // TODO You are on the GUI thread, and the first element in 
         // the progress parameter contains the last progress
         // published from doInBackground, so update your GUI
     }

     protected void onPostExecute(int result) {
       // Processing is complete, result contains the number of 
       // results you processed
     }
 }

And execute by calling

new DownloadFilesTask().execute(url1, url2, url3);
like image 173
Reto Meier Avatar answered Oct 08 '22 17:10

Reto Meier