Ojonugwa Jude Ochalifu
Ojonugwa Jude Ochalifu

Reputation: 27237

Alternative to Thread.sleep method in Android

I have this button that when clicked saves the details entered in my textfields to Google App Engine, right after the call to that onClickListener, i have an intent that starts a new activity, which displays the details I just entered. Here is the code for this:

submitButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(v.getId() == R.id.userDetailsCaptureButton) {
                new EndpointsTask().execute(getApplicationContext());
            }

            startActivity(userProfileDisplayIntent);
        }
    });

Now i want to be able to wait for a couple of seconds before making a call to startActivity after new EnpointsTask().execute(getApplicationContext) has been called. I read that using Thread.sleep causes the UI to freeze and as such isn't best suited for this. What other options are there?

Upvotes: 4

Views: 7384

Answers (3)

Yaroslav Mytkalyk
Yaroslav Mytkalyk

Reputation: 17105

Start activity in

onPostExecute()

of

EndpointsTask

Your EndPoints task should look like that

public final class EndpointsTask extends AsyncTask {

    private final Intent mUserProfileDisplayIntent;
    private final WeakReference<Activity> mActivityReference;

    EndpointsTask(final Activity activity, final Intent userProfileDisplayIntent) {
        mActivityReference = new WeakReference<Activity>(activity);
        mUserProfileDisplayIntent = userProfileDisplayIntent;
    }

    @Override
    protected void onPostExecute(Void result) {
        final Activity activity = mActivityReference.get();
        if (activity != null) {
            startActivity(mUserProfileDisplayIntent);
        }
    }
}

And then

    @Override
    public void onClick(View v) {
        if(v.getId() == R.id.userDetailsCaptureButton) {
            // make sure only one task can be launched
            if (endPointsTask == null || endPointsTask.getStatus() != AsyncTask.Status.RUNNING) {
                 endPointsTask = new EndpointsTask(YourActivity.this);
                 endPointsTask.execute();
            }
        }
        startActivity(userProfileDisplayIntent);
    }

// always cancel AsyncTasks in onStop(). You don't want it to launch anything when minimized, do you?

@Override
protected void onStop() {
    super.onStop();
    if (endPointsTask != null && endPointsTask.getStatus() == AsyncTask.Status.RUNNING) {
        endPointsTask.cancel();
    }
}

Don't pass a Context as a parameter to any thread since it can cause leaks. This means as well that inner classes should be static. Store Context as a WeakReference (use mActivityReference for Context in current example)

Upvotes: 2

PieterAelse
PieterAelse

Reputation: 3678

The solution is to use a handler with a runnable and use of the method 'postDelayed'. Example:

new Handler().postDelayed(new Runnable() {
    public void run () {
        // Do delayed stuff!
    }
}, 5000L); //5 seconds delay 

Upvotes: 6

A.D.
A.D.

Reputation: 1452

Try it with a Handler and postDelayed-method inside onClick

Upvotes: 1

Related Questions