3

我想建立一个类,每次我想做网络连接时,我都会使用它。我想先打开一个对话框,然后建立网络连接(或者从 SQL 获取一些东西,或者从 Web 下载一些东西,或者更新 SQL),然后关闭对话框。

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

我想使用AsyncTask,但我想不出一种方法来确定AsyncTask要使用哪个功能。我找到了两个解决方案,switch-case或者尝试发送带有 java 反射的函数。两种解决方案都不是很好。

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

4

2 回答 2

3

考虑使用Command设计模式。 这是 Java 示例。您可以通过回调扩展它以在完成后台工作后执行某些操作。

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);

您还需要处理方向更改

于 2013-03-03T09:44:54.257 回答
2

Android 文档有很好的示例说明如何使用AsyncTask. 这里有一个。如果你想添加一些代码来显示对话框,那么可能是这样的:

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") });
于 2013-03-03T08:45:14.883 回答