Reputation: 79
II want to build a class that every time I want to do a network connection, I'll use it. I want to open a dialog first and then make the network connection (or get something from SQL or download something from the web or update the SQL) and then close the dialog.
I need to wait for the function to end before I can continue.
I wanted to use AsyncTask
, but I can't figure out a way to determine in the AsyncTask
which function to use. I found two solutions, switch-case
or trying to send a function with java reflection. Both solutions are not too good.
Does someone have another idea or another way to do this?
Upvotes: 3
Views: 2394
Reputation: 807
Consider using the Command
design pattern.
Here is Java example. You can extend it by callbacks to do something after finishing background work.
public abstract class Command {
protected AsyncTaskCallback callback;
public Command(AsyncTaskCallback callback) {
this.callback = callback;
}
public abstract void execute();
public AsyncTaskCallback getCallback() {
return callback;
}
public interface AsyncTaskCallback {
public void onPreExecute();
public void onPostExecute();
}
}
Invoker:
public class Invoker extends AsyncTask<Void, Void, Void> {
private Command command;
public static void execute(Command command) {
new Invoker(command).execute();
}
private Invoker(Command command) {
this.command = command;
}
@Override
protected Void doInBackground(Void... params) {
return command.execute();
}
@Override
protected void onPreExecute() {
if (command.getCallback() != null) {
command.getCallback().onPreExecute();
}
}
@Override
protected void onPostExecute(Void result) {
if (command.getCallback() != null) {
command.getCallback().onPostExecute();
}
}
}
So, your AsyncTask doesn't know which command it is executing and thus can be used throughout the app. Now you can implement interface AsyncTaskCallback
in your Activity
and handle there all UI-related things you need.
Example:
public class MyActivity extends Activity implements AsyncTaskCallback {
...
public void onPreExecute() {
showProgress();
}
public void onPostExecute() {
hideProgress();
doOtherThings();
}
...
Command myCommand = new Command(this) {
@Override
public void execute() {
// Do specific background work
}
}
Invoker.execute(command);
Also you need to handle orientation changes.
Upvotes: 3
Reputation: 31045
The Android docs have good examples of how to use AsyncTask
. There's one here. If you want to add some code to show dialogs, then maybe something like this:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
// Constant for identifying the dialog
private static final int LOADING_DIALOG = 1000;
private Activity parent;
public DownloadFilesTask(Activity parent) {
// record the calling activity, to use in showing/hiding dialogs
this.parent = parent;
}
protected void onPreExecute () {
// called on UI thread
parent.showDialog(LOADING_DIALOG);
}
protected Long doInBackground(URL... urls) {
// called on the background thread
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
// called on the UI thread
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
// this method is called back on the UI thread, so it's safe to
// make UI calls (like dismissing a dialog) here
parent.dismissDialog(LOADING_DIALOG);
}
}
Before performing the background work, onPreExecute()
will be called back. This is an optional method to override in your AsyncTask
subclass, but it gives you a chance to throw up a UI before the network/database work starts.
After the background work completes, you have another opportunity to update the UI (or remove a dialog) in onPostExecute()
.
You'd use this class (from within an Activity
) like so:
DownloadFilesTask task = new DownloadFilesTask(this);
task.execute(new URL[] { new URL("http://host1.com/file.pdf"),
new URL("http://host2.net/music.mp3") });
Upvotes: 2