I came across this android example that runs an AsyncTask from a UI thread. The class ExportDatabaseTask is declared and instantiated in the Activity, and apparently it is possible to reference the activity's UI context from the onPreExecute and onPostExecute events, like this:
public class ManageData extends Activity {
private ExportDatabaseTask exportDatabaseTask;
[...]
@Override
public void onCreate(final Bundle savedInstanceState) {
[...]
ManageData.this.exportDatabaseTask = new ExportDatabaseTask();
ManageData.this.exportDatabaseTask.execute();
[...]
}
private class ExportDatabaseTask extends AsyncTask<String, Void, Boolean> {
private final ProgressDialog dialog = new ProgressDialog(ManageData.this);
protected void onPreExecute() {
this.dialog.setMessage("Exporting database...");
this.dialog.show();
}
protected Boolean doInBackground(final String... args) {
[...]
}
protected void onPostExecute(final Boolean success) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
}
}
I am trying to refactor this so that the ExportDatabaseTask is declared in another class that is not the Activity, for various reasons, and I can't quite figure out how to make it work. I am lacking some basic Java concepts here, which I readily admit.
Specifically, myActivity is null in onPreExecute(). Why is that?
// this is a click event handler in my activity that starts the export
public void onClick(View v) {
Exporter ex = new Exporter(getApplicationContext(), ActivityMain.this);
ex.exportDatabaseTask.execute();
}
//this is the utility class
public class Exporter {
public ExportDatabaseTask exportDatabaseTask;
private Context myContext;
private ActivityMain myActivity;
public Exporter(Context ctx, ActivityMain act) {
myContext = ctx;
myActivity = act;
this.exportDatabaseTask = new ExportDatabaseTask();
}
public class ExportDatabaseTask extends AsyncTask<Void, Void, Boolean> {
private final ProgressDialog dialog = new ProgressDialog(myContext);
// can use UI thread here?
protected void onPreExecute() {
// ====> this throws a Nullpointer exception:
myActivity.dialog.setMessage("Exporting database...");
myActivity.dialog.show();
}
protected Boolean doInBackground(final Void... args) {
}
protected void onPostExecute(final Boolean success) {
if (myActivity.dialog.isShowing()) {
myActivity.dialog.dismiss();
}
}
}
}
I realize that I can take the code from the pre and post-execute events and put it into the onclick handler in my activity, avoiding this question, but I am still curious why the code above does not work.