我希望建立一个每次我想要建立网络连接的类,我会使用它。 我想首先打开一个对话框,然后建立网络连接(或从SQL获取内容或从Web下载或更新SQL),然后关闭对话框。
我需要等待功能结束才能继续。
我想使用AsyncTask
,但我无法找到一种方法来确定AsyncTask
使用哪个函数。我找到了两个解决方案,switch-case
或尝试使用java反射发送函数。两种解决方案都不太好。
有人有其他想法或其他方法吗?
答案 0 :(得分:3)
考虑使用Command
设计模式。
Here is Java example。您可以通过回调对其进行扩展,以便在完成后台工作后执行某些操作。
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();
}
}
调用器:
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();
}
}
}
因此,您的AsyncTask不知道它正在执行哪个命令,因此可以在整个应用程序中使用。现在,您可以在AsyncTaskCallback
中实现接口Activity
,并处理所有与UI相关的内容。
示例:
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);
您还需要处理orientation changes。
答案 1 :(得分:2)
Android文档提供了如何使用AsyncTask
的很好示例。 There's one here。如果你想添加一些代码来显示对话框,那么可能是这样的:
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);
}
}
在执行后台工作之前,将回拨onPreExecute()
。这是一个可选方法,可以覆盖AsyncTask
子类,但它可以让您在网络/数据库工作开始之前抛出UI。
后台工作完成后,您还有机会在onPostExecute()
更新用户界面(或删除对话框)。
您可以使用此类(来自Activity
内),如下所示:
DownloadFilesTask task = new DownloadFilesTask(this);
task.execute(new URL[] { new URL("http://host1.com/file.pdf"),
new URL("http://host2.net/music.mp3") });