Search code examples
androidandroid-asynctaskbroadcastreceiverlistener

How to check (listen) asynctask status when starting activity


I have an Activity 'A' with it's child fragment, Activity 'B' and GetTask class. User launches the application and gets to Activity A. While user looks at ListView, AsyncTask is loading data for Activity B. But it may take a while and user can move to Activity B with no data for a ListView yet. So he have to wait. I'm creating a ProgressDialog here and want to check somehow when AsyncTask is completed.

Now I use static variable instance with a static method getInstance() which set to '1' in PostExecute method and then I take it in my Activity B

int instance = GetTask.getInstance();

Then I create a ProgressDialog, but I can't get AsyncTask status to know when dismiss my dialog. task.getStatus() always show RUNNING status.

I tried to make it with OnComplete listener, sample code below public class GetForeignToursTask extends AsyncTask implements OnTaskCompleteListener {

ActivityA just launches an AsyncTask:

GetTask task = new GetTask(this, null);
task.execute(url);

GetTask class sample:

    private Context context;
    OnTaskCompleteListener listener;

    private static int instance = 0;

    public GetTask(Context context, OnTaskCompleteListener listener) {
        this.listener = listener;
        this.context = context;
    }

    @Override
    public void onTaskCompleted(int status) {
        Log.d("log", status); // I don't get here at all
    }

ActivityB code:

GetTask task = new GetTask();
task.getStatus(); // here is always RUNNING
int instance = GetTask.getInstance();

if (instance != 1) {
    final ProgressDialog dialog = new ProgressDialog(ToursListActivity.this);
    dialog.setMessage("Loading...");
    dialog.show();
    // I also need to pause here until AsyncTask is done.
}

listener.onTaskCompleted(1); // error here

OnTaskCompleteListener interface:

public interface OnTaskCompleteListener {
void onTaskCompleted(int status);
}

I'm not sure I'm doing it right with all there CompleteListener. As I understood, to make CompleteListener work it should be started with an Activity which I'm going to listen, but my AsyncTask already running and I don't execute it from ActivityB. How to make it better? Or why I don't get into onTaskCompleteListener method?

I changed GetTask executing code in ActivityA to listener.onTaskCompleted(1); and getting the same error at line listener.onTaskCompleted(1); in ActivityB.

NullPointerException

Upd

ActivityB ListView dependens on ListItem which user will tap. So I think I can't load ListView before AsyncTask completed.

Solution

Well, I made it using BroadcastReceiver and static method in my AsyncTask to find out if AsyncTask completed before ActivityB is started.

Here is my code about it. In GetTask class I added method:

static boolean taskStatus = false;
public static boolean GetTaskStatus() {
    return taskStatus;
}

in onPostExecute()

Intent intent = new Intent("ru.myapp.asynctaskcompleted");
context.sendBroadcast(intent);

ActivityB

private ProgressDialog dialog;

protected void onCreate(Bundle savedInstanceState) {
    ...
    dialog = new ProgressDialog(ActivityB.this);
    taskStatus = GetTask.GetTaskStatus();
    ...
    if (!taskStatus) { // check if AsyncTask already completed
        dialog.setMessage("Loading...");
        dialog.show();
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
    } else {
        items = datasource.getSelectedItems(cid);
        setUpView(context, items);
        taskStatus = false; // in case of reloading data this should be returned to false I think
}

private BroadcastReceiver asynctaskcompleted = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "AsyncTask completed");
        datasource = new ItemsListDataSource(context);
        datasource.open();
        items = datasource.getSelectedItems(cid);
        setUpView(context, items);
        dialog.dismiss();
    }
};

public void onResume() {
    super.onResume();
    IntentFilter filter = new IntentFilter();
    filter.addAction("ru.myapp.asynctaskcompleted");
    filter.addCategory("android.intent.category.DEFAULT");
    registerReceiver(asynctaskcompleted, filter);
}

public void onPause() {
    super.onPause();
    unregisterReceiver(asynctaskcompleted);
}

Here is the link to another question I used; That's it. Thank you for your help.


Solution

  • You don't need to call getStatus(), you don't need to create a new interface OnTaskCompleteListener, and you don't need getInstance()

    Here's how you should do it.

    mProgressDialog.show();
    new GetTask()
    {
        @Override
        protected void onPostExecute(Void result)
        {
            mProgressDialog.dismiss();
    
            //this means the task is done.
        }
    }.execute(this, null);