Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fire event on AsyncTask finished

My app has a login activity and it checks the credentials via an internet website. To do so, I (have to) use an AsyncTask class. When login is successful, a global variable is set to true.

Because this is asynchronous, the activity won't wait for the result so I would like to add an event that is fired by the post-execute method of the AsyncTask class. Then a listener on the login activity will close itself and the main activity is visible.

I would like to know if and how this is possible. I have tried some examples from other posts, but can't figure it out from those.

I think I have to do the following: - create an interface in the AsyncTask class - from the post_execute method of that class, I raise the event, but how? - put a listener in the login activity, but how?

any help is appreciated.

Regards, Eric

like image 211
Eric Avatar asked Jan 25 '13 00:01

Eric


People also ask

What happens to AsyncTask if activity is destroyed?

If you start an AsyncTask inside an Activity and you rotate the device, the Activity will be destroyed and a new instance will be created. But the AsyncTask will not die. It will go on living until it completes.

What is the replacement of AsyncTask?

AsyncTask is used to perform time talking operations in android, but it's marked as deprecated from android 11. There are many alternatives are available for replacing an AsyncTask, one of the replacements is ExecutorService.

When AsyncTask is executed it goes through what steps?

An asynchronous task is defined by 3 generic types, called Params , Progress and Result , and 4 steps, called onPreExecute , doInBackground , onProgressUpdate and onPostExecute .

How many times an instance of AsyncTask can be executed?

AsyncTask instances can only be used one time.


2 Answers

I would like to add an event that is fired by the post-execute method of the AsyncTask class. Then a listener on the login activity will close itself and the main activity is visible.

onPostExecute() is already a callback, you could create another callback like you described but it is unnecessary. Simply pass a reference of your login Activity to your AsyncTask then use it to call finish() and startActivity() in onPostExecute().

like image 172
Sam Avatar answered Sep 19 '22 23:09

Sam


At first, create your post class, using Asynctask or IntentService like following...

public class PostIntentService extends IntentService implements PostTask.Observer {
    private int counter = 0;
    private int retry = 2;
    private Data mData;

    public PostIntentService() {
        super("PostIntentService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        mData = (Data) intent.getSerializableExtra("data");
        // send updating status
        Intent i = new Intent();
        i.setAction(PostResponseReceiver.ACTION_RESPONSE);
        i.addCategory(Intent.CATEGORY_DEFAULT);
        i.putExtra("status", "updating");
        sendBroadcast(i);
        execute();
        counter++;
    }

    @Override
    public void onSuccessPost(String result) {
        // send success status
        Intent i = new Intent();
        i.setAction(PostResponseReceiver.ACTION_RESPONSE);
        i.addCategory(Intent.CATEGORY_DEFAULT);
        i.putExtra("status", "success");
        sendBroadcast(i);
    }

    @Override
    public void onFailedPost(String result) {
        if (counter < retry) {
            execute();
            counter++;
        }
        else {
            // send failed status
            Intent i = new Intent();
            i.setAction(PostResponseReceiver.ACTION_RESPONSE);
            i.addCategory(Intent.CATEGORY_DEFAULT);
            i.putExtra("status", "failed");
            i.putExtra("data", mData);// for reproduct
            sendBroadcast(i);
        }
    }
    private void execute() {
        PostTask task = new PostTask(this);
        task.execute();
    }
}

At second, create your class (extended BroadcastReceiver) which receives the intent when a post finished.

public class PostBroadcastReceiver extends BroadcastReceiver {
    public static final String ACTION_RESPONSE = "com.example.android.intent.action.POST_PROCESSED";
    private static final int POST_REQUEST = 100;
    private Observer mObserver;

    public PostBroadcastReceiver(Observer observer) {
        mObserver = observer;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getStringExtra("status").equals("updating")) {
        }
        else if (intent.getStringExtra("status").equals("success")) {
            if (mObserver != null) {
                mObserver.onPostFinished();
            }
        }
        else if (intent.getStringExtra("status").equals("failed")) {
            if (mObserver != null) {
                mObserver.onPostFailed();
            }
        }
    }

    public interface Observer {
        public void onPostFinished();
        public void onPostFailed();
    }
}

Register this service in your Manifest file.

<service android:name=".PostIntentService" />

Register this reciever in onCreate of your Main Activity.

IntentFilter filter = new IntentFilter(PostBroadcastReceiver.ACTION_RESPONSE);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new PostResponseReceiver(this);
registerReceiver(receiver, filter);

And implement following method in your Main activity.

public void onPostFinished() {
    Log.d("onPostFinished", "onPostFinished");
}
public void onPostFailed() {
    Log.d("onPostFailed", "onPostFailed");
}

Don't forget Unregister this reciever in onDestroy of your Main Activity.

unregisterReceiver(receiver);

Finally, execute the transfer in your login Activity.

Intent intent = new Intent(this, PostIntentService.class);
intent.putExtra("data", mData);
startService(intent);
like image 25
Mitsuaki Ishimoto Avatar answered Sep 18 '22 23:09

Mitsuaki Ishimoto