15

Google 使用varargs中的参数的原因是什么AsyncTask?例如方法execute()doInBackground()并且publishProgress()都使用[Type]...符号。

我认为这使它“更难”使用,所以他们必须有一些我忽略的充分理由?


所以,要么我们没有参数,要么有一个参数,要么有多个参数。让我们分解一下:

  1. 无参数(简单):Params参数就是Void这样。(这些方法不能使用它......所以这很安全。)

  2. 一个参数:在这里,我至少觉得有必要在doInBackground()方法的开头做一个检查。例如,这是一个接收Integer并产生类型结果的任务Double

    public Double doInBackground(Integer... myParameters) {
        // we are only expecting one parameter
        if (myParameters.length != 1)
            throw new IllegalArgumentException("!= 1");
    
        return 100d * myParameters[0];
    }
    
  3. 不止一个参数。现在这里一定是谷歌做出正确选择的地方吗?但正如我所见,要么你对相同类型的参数列表感兴趣,要么你想要不同类型的参数。谷歌只解决了其中一种情况(对于不同的类型,您需要某种通用接口。在许多情况下,我最终Object...得到的结果并不是真正的类型安全......)


那么,如果我们完全删除它会出现什么问题varargs呢?这是方法的子集:

class AsyncTask<Param, Progress, Result> {

    abstract Result doInBackground(Param param);
    void publishProgress(Progress progress) { ... }
}

这适用于上述所有情况。例如,如果我们想处理一个参数数组,我们可以只使用数组类型param

class MyAsyncTask extends AsyncTask<String[], Integer, String> { 

    String doInBackground(String[] param) {
        return Arrays.toString(param);
    }
}

我看不出它什么时候会有实际用途。但我确定我错过了一些我需要知道的东西。:)

4

2 回答 2

2

我认为 vararg 参数只是让您在调用执行AsyncTask.

只要我们想知道为什么 AsyncTask 是这样设计的::-)

在我看来,ParamResult模板对于完成同样的事情并不是真正必要的。

当您编写自己的AsyncTask时,您将其子类化。除了为Paramand声明实际类型Result,您还可以将 final 字段添加到您的子类 (Params) 并将可修改字段添加到您的子类 (Result)。例如:

public class MyAsyncTask extends AsyncTask<Void> {
    // Input Params
    private final int inParam1;
    private final String inParam2;

    // Output Results
    private Bitmap resultBitmap;

    public MyAsyncTask(int param1, String param2) {
        inParam1 = param1;
        inParam2 = param2;
    }

    @Override
    protected void doInBackground() {
        // use param1 and param2 as input to the background process.
        ...
        ...
        // Finished: assign to result
        resultBitmap = ....;
    } 

    @Override
    protected void onPostExecute() {
        // Send result to UI.
        ... resultBitmap ...
        ...
        resultBitmap = null;
    }
}

不需要泛型,也许除了显示进度。

这是我通常会做的事情,特别是如果结果是Bitmap. 在所有设置和完成之后,返回doInBackground和处理的值未设置为 null,并且它以这种方式偷偷地“泄漏”(由 completed/finished 保存在内存中的位图引起的内存错误)。onPostExecuteBitmapsAsyncTasks

于 2013-03-06T15:01:23.343 回答
1

我认为你是对的,类型参数的唯一用法Params是 in Params...,这意味着它确实Params[]是这里想要的。但是现在 API 只适用于数组类型,它遗漏了很多非数组类型。

可变参数的唯一优势是在调用站点,但也不是很多 -

谷歌版本:

AsyncTask<String> task = ...
task.execute("a", "b");

你的版本:

AsyncTask<List<String>> task = ...
task.execute(Arrays.asList("a", "b"));
于 2013-03-06T00:29:25.703 回答