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>());
}
}
Worker threads However, note that you cannot update the UI from any thread other than the UI thread or the "main" thread.
Alternative 1: Using Executor and Handler The executor will help in performing any task in the background and the handler will help to make UI changes.
There are two simple solutions that cover most situations: Either check AsyncTask. isCancelled() on a regular basis during your long-running operation, or keep your Thread interruptible. Either way, when you call AsyncTask. cancel() these methods should prevent your operation from running longer than necessary.
This class was deprecated in API level 30. AsyncTask was intended to enable proper and easy use of the UI thread. However, the most common use case was for integrating into UI, and that would cause Context leaks, missed callbacks, or crashes on configuration changes.
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;
}
You never call setSuperGroupList()
so the listener
remains null. Better to put listener into the constructor of your task.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With