max4ever
max4ever

Reputation: 12142

Android wait AsyncTask to finish

I have a function, AppHelper.isOnline(Context context), I call in various parts of my application to check that a session didn't timeout before making an HTTP request.

public void onClick(View v) {
        Intent intent = null;
        switch (v.getId()) {

        case R.id.buttonPagamenti:
            if (AppHelper.isOnline(this))
            {
                //here AppHelper.isOnline should have finished it's async task
                intent = new Intent(this, OrdineCreaActivity.class);
                this.startActivityForResult(intent, R.id.buttonPagamenti);
            }
            break;
...

Inside AppHelper.isOnline(), I am executing an AsyncTask that logs in, thus making a network request, which can't be run on UI because otherwise I get an exception. I need to wait for it to finish BEFORE resuming with the code inside the if. How can I do this ?

Problem is the activity starts firsts, then the AsyncTask executes, so when the activity expects a valid logged in session, it breaks.

Upvotes: 41

Views: 98822

Answers (4)

Boris Strandjev
Boris Strandjev

Reputation: 46943

You have two options:

Either use the AsyncTask's method get(long timeout, TimeUnit unit) like that:

task.get(1000, TimeUnit.MILLISECONDS);

This will make your main thread wait for the result of the AsyncTask at most 1000 milliseconds (as per @user1028741 comment: actually there is also infinetly waiting method - AsyncTask#get() which might also do the work for you in some cases).

Alternatively you can show a progress dialog in the async task until it finishes. See this thread (No need for me to copy past the code). Basically a progress dialog is shown while the async task runs and is hidden when it finishes.

You have even third option:" if Thread is sufficient for your needs you can just use its join method. However, if the task is taking a long while you will still need to show a progress dialog, otherwise you will get an exception because of the main thread being inactive for too long.

Upvotes: 83

Mark Cramer
Mark Cramer

Reputation: 2854

Rafiq's response did not work for me - the app hung. I think the reason has to do with the nature of isCancelled(): "Returns true if this task was cancelled before it completed normally." If the task completes normally (i.e. is not cancelled) then while(!task.isCancelled()) { } will loop forever.

To solve this create a Boolean flag that you instatiate to false and then flip to true in task.onPostExecute(). Then do while(!flag) { } before switching Activities. Additionally, if you'd like to give the main thread a 'break' to let the AsyncTask process a little faster, you can do try this:

while (!flag) {
    try { Thread.sleep(100); }
    catch (InterruptedException e) { e.printStackTrace(); }
}

It seems to be working well for me.

Upvotes: 2

Shankar Agarwal
Shankar Agarwal

Reputation: 34765

intent = new Intent(this, OrdineCreaActivity.class);
context.startActivityForResult(intent, R.id.buttonPagamenti);

Write the above lines in onPostExecute() of you AysncTask. Because if we are using AsyncTask it wont wait there until the task complete.

Upvotes: 1

Rafiq
Rafiq

Reputation: 2000

try using

if (AppHelper.isOnline(this))
        {
            while(!task.isCancelled()){
               // waiting until finished protected String[] doInBackground(Void... params)          
              } 
            intent = new Intent(this, OrdineCreaActivity.class);
            this.startActivityForResult(intent, R.id.buttonPagamenti);
        }    

For more information read http://developer.android.com/reference/android/os/AsyncTask.html

Upvotes: 3

Related Questions