Updating UI thread from AsyncTask in open class

I am trying to separate some AsyncTask classes into public (separate) functions so that I don't have to rewrite so much code. I almost have it, except for one very important aspect. The AsyncTask function compiles an ArrayList, making php calls to the server. When this list is complete, I need to update the counter in the main user interface thread. I found a really nice answer here , but I have a little difficulty in his work.

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

Here is the Activity call:

 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 AsyncTask . Note that this 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>()); } } 
+6
source share
4 answers

Just add the OnTaskCompleted listener parameter to the asyncTask constructor GetSuperGroups . Then go through this when you execute 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; } 
+7
source

You never call setSuperGroupList() , so the listener stays empty. It is better to put the listener in the constructor of your task.

+2
source

You are choosing the right path. But I do not understand the problem in the onPostExecute (..) method. This is about null pDialog or null sg_list. If the problem is in sg_list, please check if the php method works or not? may be a resolution problem in the ffo file of the php file. Therefore, my advice is to first test your method on the user interface thread. Then change it to a background thread.
You can also put a toast in the onPostExecute method to check the contents of sg_list.

0
source

You need to add the setListener function:

 public class TaskComplete { public OnTaskCompleted onTaskListenerComplete; public interface OnTaskCompleted { void onTaskCompleted(ArrayList<String> list); } public void setOnTaskComplete(OnTaskCompleted onTaskListenerComplete){ this.onTaskListenerComplete = onTaskListenerComplete; } } 

And in the Office, define and install 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 this is helpful.

0
source

Source: https://habr.com/ru/post/952635/


All Articles