AndroidDev
AndroidDev

Reputation: 21237

Updating UI Thread from AsyncTask in public class

I'm trying to split off some AsyncTask classes into public (separate) functions so that I'm not having to rewrite so much code. I almost have it, except for one very important aspect. The AsyncTask function compiles an ArrayList by making php calls to a server. When this list is complete, I need to update a spinner on the main UI thread. I found a really nice answer here but I'm having a little difficulty making it work.

Here is a scaled down version of what I have: (note that at this point, all I am trying to do is to call a Toast message to prove that the round trip is working)

Here is the calling Activity:

public class MyActivity extends Activity implements OnTaskCompleted {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sg_list = new ArrayList<String>();
        new GetSuperGroups(UpdateAffiliationsPreferences.this, context, "Retrieving Group List...").execute();
    }

    public void onTaskCompleted(ArrayList<String> list) {
        Toast.makeText(getApplicationContext(), "hello from async", Toast.LENGTH_SHORT).show();
    }

}

This is the interface:

public interface OnTaskCompleted {
    void onTaskCompleted(ArrayList<String> list);
}

And finally, here is the AsyncTask. Note that it is a Public class:

public class GetSuperGroups extends AsyncTask<String, String, ArrayList<String>> {

    private Activity activity;
    private Context context;
    private String progressMsg;
    private ProgressDialog pDialog;
    private ArrayList<String> sg_list;
    private OnTaskCompleted listener;

    public GetSuperGroups(Activity activity, Context context, String progressMsg) {
        this.activity = activity;
        this.context = context;
        this.progressMsg = progressMsg;
    }

    public void setSuperGroupList (OnTaskCompleted listener){
        this.listener = listener;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(context);
        pDialog.setMessage(progressMsg);
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();
    }

    @Override
    protected ArrayList<String> doInBackground(String... args) {

        sg_list = new ArrayList<String>();
        //make a php call, compile the ArrayList    
        return sg_list;
    }

    protected void onPostExecute(ArrayList<String> sg_list) {
        pDialog.dismiss();
        //this next line causes a null pointer error
        //note that I am throwing away the array list for now
        //all I want to do is prove that I can call the Toast back in the calling Activity
        listener.onTaskCompleted(new ArrayList<String>());
    }
}

Upvotes: 6

Views: 7547

Answers (4)

Vipul Purohit
Vipul Purohit

Reputation: 9827

Just add OnTaskCompleted listener parameter in your asyncTask constructor GetSuperGroups. Then pass this when you execute your asyncTask.

public class MyActivity extends Activity implements OnTaskCompleted {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            sg_list = new ArrayList<String>();
            new GetSuperGroups(UpdateAffiliationsPreferences.this, context, "Retrieving Group List...", this).execute();
        }

        public void onTaskCompleted(ArrayList<String> list) {
            Toast.makeText(getApplicationContext(), "hello from async", Toast.LENGTH_SHORT).show();
        }

    }

and

  public class GetSuperGroups extends AsyncTask<String, String, ArrayList<String>> {

        private Activity activity;
        private Context context;
        private String progressMsg;
        private ProgressDialog pDialog;
        private ArrayList<String> sg_list;
        private OnTaskCompleted listener;

        public GetSuperGroups(Activity activity, Context context, String progressMsg, OnTaskCompleted listener) {
            this.activity = activity;
            this.context = context;
            this.progressMsg = progressMsg;
            this.listener = listener;
        }

Upvotes: 7

yagi_chan
yagi_chan

Reputation: 13

You need to add a function setListener:

public class TaskComplete {
    public OnTaskCompleted onTaskListenerComplete;

    public interface OnTaskCompleted {
        void onTaskCompleted(ArrayList<String> list);
    }

    public void setOnTaskComplete(OnTaskCompleted onTaskListenerComplete){
        this.onTaskListenerComplete = onTaskListenerComplete;
    }
}

And in Activity, define and set it:

public class MyActivity extends Activity implements OnTaskCompleted {
    public TaskComplete task;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        sg_list = new ArrayList<String>();
        task.setOnTaskComplete(this);
        new GetSuperGroups(UpdateAffiliationsPreferences.this, context, "Retrieving Group List...").execute();
    }

    public void onTaskCompleted(ArrayList<String> list) {
        Toast.makeText(getApplicationContext(), "hello from async", Toast.LENGTH_SHORT).show();
    }

}

In AsyncTask:

protected void onPostExecute(ArrayList<String> sg_list) {
    pDialog.dismiss();
    //this next line causes a null pointer error
    //note that I am throwing away the array list for now
    //all I want to do is prove that I can call the Toast back in the calling Activity
    activity.onTaskCompleted(new ArrayList<String>());
}

Hope it useful.

Upvotes: 0

ANjaNA
ANjaNA

Reputation: 1426

you fallowing the right path. But I'm not clear the problem in the onPostExecute(..) method. Is it about null pDialog or null sg_list. If problem in the sg_list please check is the php method working or not? may be problem with the permission in manifest file foe php service.
So my advice to check your method first on UI thread. Then change it to do in background thread.
Also you can put the toast at onPostExecute method to check the sg_list content.

Upvotes: 0

Alexander
Alexander

Reputation: 48232

You never call setSuperGroupList() so the listener remains null. Better to put listener into the constructor of your task.

Upvotes: 2

Related Questions