android - 我应该将参数提供给构造函数还是 AsyncTask.execute(params)?

标签 android android-asynctask

我试图弄清楚为什么 Android 的 AsyncTask 通过 execute 提供参数,以及为什么似乎没有将 then 传递给构造函数(至少在文档中)。

在我看来,这是最有意义的方式(当然,我正在处理的实际任务不仅仅是一个总和计算器):

public class FooTask extends AsyncTask<Void, Integer, Long> {
    private ProgressBar progressBar;
    private int[] data;

    public FooTask(ProgressBar progressBar, int... data) {
        this.progressBar = progressBar;
        this.data = data;
    }

    protected void onPreExecute() {
        progressBar.setMax(data.length);
        progressBar.setProgress(0);
    }

    protected Long doInBackground(Void... _) {
        long sum = 0;
        for (int i = 0; i < data.length; i++) {
            sum += data[i];
            publishProgress(i);
        }
        return sum;
    }

    protected void onProgressUpdate(Integer... progress) {
        progressBar.setProgress(progress[0]);
    }

    protected void onPostExecute(Long result) {
        Log.i(TAG, "Sum: " + result);
    }
}

这样使用:

new FooTask(progressBar, 1, 2, 3).execute();

但是,这不是文档所谈论的方式;它使用 execute() 的参数,像这样(极端地根本不使用构造函数,但仍然使用一个字段,否则会太可怕):

public class FooTask extends AsyncTask<Object, Integer, Long> {
    private ProgressBar progressBar;
    private boolean isMaxSettingUpdate = true;

    protected Long doInBackground(Object... params) {
        progressBar = params[0];
        long sum = 0;
        for (int i = 1; i < data.length; i++) {
            sum += (int) data[i];
            publishProgress(i - 1, data.length);
        }
        return sum;
    }

    protected void onProgressUpdate(Integer... progress) {
        progressBar.setMax(progress[1]);
        progressBar.setProgress(progress[0]);
    }

    protected void onPostExecute(Long result) {
        Log.i(TAG, "Sum: " + result);
    }
}

这个任务的执行看起来更像这样:

new FooTask().execute(progressBar, 1, 2, 3);

我考虑的另一个选项是将进度条提供给构造函数并将数据提供给执行调用,但是我仍然不能使用 onPreExecute 因为我不知道最大值。 (我宁愿使用真正的最大值,而不是任意设置最大值并计算百分比......看起来更好。)

余额在哪里?我应该怎么办?使用构造函数有什么错误

最佳答案

为什么文档在方法中做所有事情可能是他们选择示例的结果。通常,您更有可能扩展您的 AsyncTask 并且只使用 doInBackground(),而不是构造函数。

无论如何,documentation states :

Memory observability


AsyncTask guarantees that all callback calls are synchronized in such a way that the following operations are safe without explicit synchronizations.

•Set member fields in the constructor or onPreExecute(), and refer to them in > doInBackground(Params...).

•Set member fields in doInBackground(Params...), and refer to them in onProgressUpdate(Progress...) and onPostExecute(Result).

这意味着你应该擅长这两种方法。

附带说明,我使用了带有参数构造函数的 AsyncTask 没有问题,因此我可以备份文档中的内容。

此外,对于您的具体情况,除非 ProgressBar 事先设置了不同的最大值,否则它应该默认为 100。这意味着您可以让构造函数仅在 中接受ProgressBar 并让 doInBackground() 接受数据(这也应该是一个成员变量)。然后在更新进度时,做

(progress[0]/data.length) * 100

它不会是完美的,如果你想提高准确性,你可以转换为 double,但这应该使代码更容易理解。

关于android - 我应该将参数提供给构造函数还是 AsyncTask.execute(params)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16765415/

相关文章:

java - Android Webview 布局无法正确显示

java - 如何使用 FusedLocationProviderClient 在 GoogleMap 中获取当前位置

android - 取消所有 Volley 请求 Android

java - Android 异步任务在服务中使用时不起作用?

android - 当用户按下主页按钮时,不会调用 onSaveInstanceState()

java - 如何设置 onItemClickListener

java - 将新数据追加到 ArrayList 的简单方法

android - Kotlin - 如何下载 .mp3 文件并保存到内部存储

android - AsyncTask doInBackground 不运行

android - 处理程序 vs AsyncTask vs 线程