使用Asynctask调用多个函数进行网络连接

时间:2013-03-03 07:49:06

标签: android android-asynctask

我希望建立一个每次我想要建立网络连接的类,我会使用它。 我想首先打开一个对话框,然后建立网络连接(或从SQL获取内容或从Web下载或更新SQL),然后关闭对话框。

我需要等待功能结束才能继续。

我想使用AsyncTask,但我无法找到一种方法来确定AsyncTask使用哪个函数。我找到了两个解决方案,switch-case或尝试使用java反射发送函数。两种解决方案都不太好。

有人有其他想法或其他方法吗?

2 个答案:

答案 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") });