0

I've made an app that sends a request to a webserver in a specified interval and gets XML data. It then parses the XML data, gets information from the phone (text messages, contacts or something similar) and shoots it back to the server with a http post request.

The problem is that it usually takes a few seconds for the app to get the info, which often leaves the app crashing. A dialog comes up saying the app has become unresponsive and asks if i want to close the app or wait, if i press wait it eventually starts working again.

Is AsyncTask the right solution to this problem?

Another thing i don't really understand is how AsyncTask actually works. Let's say i have two methods that do a lot of work and crashes the app, can i put both of them in one AsyncTask and just call them from doInBackground()?

qwerty
  • 5,166
  • 17
  • 56
  • 77

3 Answers3

1

I have also implemented something similar you are trying. That is sending request to server, receive XML response, parse XML, show result. View This. I have used AsyncTask for this.

Here is how i have implemented it using AsynTask

private class AsyncClass extends AsyncTask<Void, Void, Bundle>{
    @Override
protected Bundle doInBackground(Void... arg0) {
    Bundle b=startProcess();        

// startBundle() method do all the processing and return result in a bundle. You can as many methods from within startBundle() method

    return b;
}       

@Override
protected void onPostExecute(Bundle result) {
    Log.d(TAG , "In onPostExecute");
    dialog.dismiss();
    if(result==null)
        Toast.makeText(cont, "Can't process query.\nTry again later.", Toast.LENGTH_LONG).show();
    else{
        Intent in = new Intent(cont, QueryResultDisplay.class);
        Log.d(TAG , "Displaying");
        in.putExtras(result);        
        cont.startActivity(in);           
    }
}
Community
  • 1
  • 1
Pargat
  • 769
  • 9
  • 23
  • So if i understand correctly, startBundle() is another method within the AsyncClass class that does all of the hard work? This seems promising. – qwerty May 18 '12 at 12:21
  • And also, can i call the AsyncTask from any classes? As it is now, i have a Main class that shows the GUI, and then i set up an AlarmManager that calls a BroadcastReceiver every X minutes. The BroadcastReceiver is in another class, and currently that's the class that does all the hard work. Can i move all of the hard-work-methods to an AsyncTask class and call the AsyncTask class from the BroadcastReceiver? Sorry if this is confusing, i hope you get it. – qwerty May 18 '12 at 12:26
  • @qwerty AsyncTask class is implemented as a sub class to any main class. From main class method we can call AsyncTask by writing - new AsyncClass().execute(); And also not that startBundle in this case was a method in main class. You can call main class method from your broadcast receiver which will further call asyncTask using "new AsyncClass().execute();" – Pargat May 18 '12 at 12:38
  • Go thru AsyncTask doc example [here](http://developer.android.com/reference/android/os/AsyncTask.html) – Pargat May 18 '12 at 12:53
  • Alright, thank you! I will play with it and hopefully i get it working. :) – qwerty May 18 '12 at 13:36
  • I got it working but i'm having another issue regarding the context now, if you don't mind i posted another question here: http://stackoverflow.com/questions/10656485/android-java-cant-access-getcontentresolver-from-context – qwerty May 18 '12 at 16:40
1

I give you brief description about your problem.

There are many possibility that you don't get data from server

  1. if your network speed is very slow and you try to get all the information from server and XML data then in this case if network crash then it show you error

  2. if you're making request to that page which is not in server

Now, if you are facing the problem in code, then I give you the complete code of AsyncTask class which I had implemented in my project and it work fine.

private class GetLoginResponse extends AsyncTask<Void, Void, Boolean> {
    private ProgressDialog progressDialog;
    private String email;
    private String password;

    public GetLoginResponse(String emailId, String paswd) {
        this.email = emailId;
        this.password = paswd;
    }

    @Override
    protected void onPreExecute() {
        progressDialog = ProgressDialog.show(LoginActivity.this, "",
                "Loading....", true, false);
    }

    @Override
    protected Boolean doInBackground(Void... params) {

        try {
            DefaultHttpClient httpclient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
                            HttpResponse response = httpclient.execute(httpGet);
        //here u can check the reponse is ok and 200 
                         } catch (NetworkException e) {
            isNetworkError = true;
        }
        return false;
    }

    @Override
    protected void onPostExecute(Boolean data) {
        progressDialog.dismiss();
        System.out.println("lOGIN RESPONSE for email = " + email + data);
    }
}// end AsyncTask

This would solve your problem.

Pang
  • 9,564
  • 146
  • 81
  • 122
itechDroid
  • 1,031
  • 1
  • 11
  • 17
0

Yes, you can use AsyncTask.

The code called in doInBackground() must not touch the UI.

You can touch the UI thread with publishProgress().

lulumeya
  • 1,619
  • 11
  • 14