我应该给构造函数还是给 AsyncTask.execute(params) 参数? [英] Should I give params to the constructor or to AsyncTask.execute(params)?

查看:20
本文介绍了我应该给构造函数还是给 AsyncTask.execute(params) 参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to figure out why Android's AsyncTask gives parameters through execute and why passing then to the constructor doesn't seem to be done (in the docs, at least).

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

This is the way that seems to me to make the most sense (naturally, the actual task I'm working with is more than just a sum calculator):

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() 的参数,就像这样(极端情况下根本不使用构造函数,但仍然使用一个字段,否则会太可怕):

However, this isn't the way the documentation talks about doing it; it uses arguments to execute(), like this (taken to the extreme of not using a constructor at all, but still using one field because otherwise it'd be too horrible):

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

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

Execution of this task would look more like this:

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

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

One other option I considered was giving the progress bar to the constructor and the data to the execute call, but then I still can't use onPreExecute as I don't know the max value. (I would prefer to use a true max rather than setting the max value arbitrarily and calculating the percentage... just seems nicer.)

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

Where's the balance? What should I do? Is there anything wrong with using the constructor?

推荐答案

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

As to why the docs do everything in the method can be as a result of their example choice. Usually, you're more likely to extend your AsyncTask and only use doInBackground(), not the constructor.

无论如何,文档说明:

内存可观察性

AsyncTask 保证所有回调调用在这样的情况下同步一种无需明确说明即可安全执行以下操作的方法同步.

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

•在构造函数中设置成员字段或onPreExecute(),并在> doInBackground(Params...)中引用它们.

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

•在doInBackground(Params...)中设置成员字段,并在onProgressUpdate(Progress...) 和 onPostExecute(Result).

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

这意味着您应该擅长这两种方法.

This means that you should be good with both approaches.

作为旁注,我使用了带有参数化构造函数的 AsyncTask 没有问题,因此我可以备份文档中的内容.

And as a side note, I have used an AsyncTask with a param-ed constructor without issues, so I can back up what the documentation states.

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

Also, for your specific case, unless the ProgressBar has had a different max value set beforehand, it should default to 100. This means that you can have your constructor accept in just the ProgressBar and have doInBackground() accept in the data (which should also be a member variable). Then when updating the progress, do

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

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

It won't be perfect, and you can convert to double if you want to increase accuracy, but this should make the code easiest to understand.

这篇关于我应该给构造函数还是给 AsyncTask.execute(params) 参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆