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

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

问题描述

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

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

我考虑的另一个选项是将进度条提供给构造函数,将数据提供给execute调用,但是由于我不知道最大值,所以我仍然不能使用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.

无论如何,文档状态:

内存可观察性

Memory observability

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天全站免登陆