Reputation: 21237
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
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
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
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
Reputation: 48232
You never call setSuperGroupList()
so the listener
remains null. Better to put listener into the constructor of your task.
Upvotes: 2