0

I am using Asynctask to load all the contacts from the device. Although it has been discussed many times that Contacts.Contract is really slow and take me 10-15 secs to load all contacts data with image and all other data like email etc. So I have decided to start a service with asynctask on the splash screen. Now the problem is I have activity series A-B-C-D Asynctask starts in Activity A and I want Contacts in Activity D. If all contacts is loaded till user reaches Activity D then its ok. But if user reaches Activity D and service is still running than I need to make user wait.

So my question is HOW TO WAIT FOR ASYNCTASK TO FINISH in Activity D. I will show a simple progress bar in activity D till Asynctask finishes. BUT HOW?

Cyph3rCod3r
  • 1,978
  • 23
  • 33

6 Answers6

1

To wait for AsyncTask to finish you can use get() method. From documentation of get() method:

Waits if necessary for the computation to complete, and then retrieves its result.

AsyncTask - get()

But this will make your main thread wait for the result of the AsyncTask.

Another way would be that you can show a progress dialog in the async task until it finishes. This way you can get the status calling:

task.getStatus() == Status.RUNNING

And if the status is Status.RUNNING you will just show the progress dialog until will be finished. So, as an example:

    final AsyncTask task = MyAsyncTask.getInstance();

    final Thread waitingThread = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                // ...
                // show progress dialog
                while(task.getStatus() != Status.FINISHED) {
                    TimeUnit.SECONDS.sleep(1);
                }
                result = task.get();
                // ...
                // hide progress dialog
            } catch (InterruptedException e) {
                // TODO log
            }
        }
    });

    waitingThread.start();

The task object is your asyncTask. You can make it Singleton and start in Activity A, and get instance of it in Activity D.

public class MyAsyncTask extends AsyncTask<Void, Void, Void>{

        private static MyAsyncTask instance;

        private MyAsyncTask(){}

        public static MyAsyncTask getInstance() {
            // check status if we want to execute it again
            if (instance == null) {
                instance = new MyAsyncTask();
            } else if (instance.getStatus() == Status.FINISHED) {
                instance = new MyAsyncTask();
            }

            return instance;
        }

        @Override
        protected Void doInBackground(Void... params) {
            // do smth
            return null;
        }
}

Haven't tried this in action but I think it will work.

yyunikov
  • 5,719
  • 2
  • 43
  • 78
  • `get()` blocks the ui thread waiting fro the result. This makes Asynctask no more Asynchronous. So this suggestion is wrong – Raghunandan Mar 31 '14 at 10:27
  • You should not block the ui thread. http://developer.android.com/training/articles/perf-anr.html and this http://developer.android.com/guide/components/processes-and-threads.html – Raghunandan Mar 31 '14 at 10:34
  • I have suggested another way to do it. Please check my answer. – yyunikov Mar 31 '14 at 10:41
  • The "task" object is your asyncTask. You can make it Singleton and start in Activity A, and get instance of it in Activity D. – yyunikov Mar 31 '14 at 11:00
  • What if my asynctask is an Inner type of my Service class? – Cyph3rCod3r Mar 31 '14 at 11:53
  • It depends on how it is implemented. If everything is done in AsyncTask then it doesn't matter. You can post the code of your AsyncTask. – yyunikov Mar 31 '14 at 13:22
1

I have an idea to make async series in just one async task:

protected Boolean doInBackground(String... params) {
            if(params[0] == "taskA") {
              //do somthing
              params[0] = "taskB";
            }
            if(params[0] == "taskB") {
              //do somthing
              params[0] = "taskC";
            }
            if(params[0] == "taskC") {
              //do somthing
              params[0] = "taskD";
            }
            if(params[0] == "taskD") {
              //do somthing
              return true;
            }

And in your main thread just call async task like this:

ShowMyProgress();
new MyAsyncTask().execute("taskA");

And finally you can hide your progress on onPostExecute like:

protected void onPostExecute(final Boolean success) {
        if (success) {
            ....

            HideMyProgress();
        }
}
0

you can do

myAsyn asyn = new myAsyn();
asyn.execute();

while(asyn.getStatus()!=Aynctask.Status.Finished)
{
Thread.sleep(100);
}

instead of waiting for asyntask to finish, you can simply show a progress dialog.

public class myAsyn extends AsyncTask<Void, Void, Void>{


    private ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        super.onPreExecute();
        dialog = new ProgressDialog(context);
        dialog.setMessage("Loading...");
        dialog.setCanceledOnTouchOutside(false);
        dialog.show();
    }

    @Override
    protected Void doInBackground(String... arg0) {
        // TODO Auto-generated method stub
        //do your work
    }

    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        dialog.dismiss();
      }
     }
Waqar Ahmed
  • 5,005
  • 2
  • 23
  • 45
  • I know how to use it but what if I started it from service and wanna wait for it in my Activity D? I want to Fulfill a Listview in Activity D – Cyph3rCod3r Mar 31 '14 at 10:50
0

It is simple i will explain..

You can get the status of the async task task...like this

if (o2.getStatus() == Status.FINISHED) { ////o2 is a asynch task instance...

} else if (o2.getStatus() == Status.RUNNING) {

} else if (o2.getStatus() == Status.PENDING) {

}
Naveen Kumar Kuppan
  • 1,424
  • 1
  • 10
  • 12
  • My asynctask is started from service and has its object in service what should I do if I want it in my Activity which had NOT STARTED IT – Cyph3rCod3r Mar 31 '14 at 10:51
0

Please try this

public class LoadData extends AsyncTask<Void, Void, Void> {
    ProgressDialog progressDialog;
    //declare other objects as per your need
    @Override
    protected void onPreExecute()
    {
        progressDialog= ProgressDialog.show(YourActivity.this, "Progress Dialog Title Text","Process Description Text", true);

        //do initialization of required objects objects here                
    };      
    @Override
    protected Void doInBackground(Void... params)
    {   

         //do loading operation here  
        return null;
    }       
    @Override
    protected void onPostExecute(Void result)
    {
        super.onPostExecute(result);


  progressDialog.dismiss();
    };
 }

You can call this using

LoadData task = new LoadData();
task.execute();

To check whether your Service is still running::

private boolean isMyServiceRunning() {
    ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
        if (MyService.class.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}
ASP
  • 3,645
  • 1
  • 31
  • 45
  • I know ho to use asynctask mahn but the thing is starting and handling it in one activity taking a lot of time. So I am starting it on my activity A so that user do not wait for 10 sec on a single screen and the time will be splitted – Cyph3rCod3r Mar 31 '14 at 10:53
  • Cause its taking too much time – Cyph3rCod3r Mar 31 '14 at 10:59
  • yeah I can do that but I have to wait for asynctask to complete and for how long do I check this method? – Cyph3rCod3r Mar 31 '14 at 11:41
0

AsyncTask has basically onPreExecute and doInbackground, and onPostExecute exists. The meaning of each!

onPreExecute: Runs on the UI thread before doInBackground (Params. ..).

opPostExecute: Runs on the UI thread after doInBackground (Params. ..). The specified result is the value returned by doInBackground (Params. ..).

This method won't be invoked if the task was cancelled.

The order in which the calls

One. onPreExecute

Two. doInbackground

Three. onPostExecute

However doInbackground operate in the other thread.

Must be treated so well doInbackground result is passed three times because of onPreExecute() to create a progress bar progress bar to end its onPostExecute could work.

ASP
  • 3,645
  • 1
  • 31
  • 45
chakangost
  • 46
  • 2