AsyncTask varargs参数的用途

时间:2013-03-06 00:01:02

标签: java android android-asynctask

Google对AsyncTask中的参数使用varargs的原因是什么?例如,方法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. 多个参数。现在这里必须是Google做出正确选择的地方吗?但正如我所看到的那样,您要么对相同类型的参数列表感兴趣,要么不同类型参数。谷歌只解决了其中一种情况(不同类型你需要某种通用界面。在很多情况下,我最终得到的是Object...,这不是真正的类型安全......)


  4. 那么,如果我们完全删除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);
        }
    }
    

    我不知道什么时候它可以用于任何实际用途。但我确定我错过了一些我需要了解的东西。 :)

2 个答案:

答案 0 :(得分:2)

我认为当你调用执行 AsyncTask时,vararg参数会让它更方便一些。

只要我们想知道为什么AsyncTask的设计方式如下: - )

在我看来,ParamResult模板实际上并不是必需的。

当您编写自己的AsyncTask时,您将其子类化。您可以将最终字段添加到子类(Params),并将可修改字段添加到子类(Result),而不是声明ParamResult的实际类型。 E.g:

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

不需要任何通用,可能除了显示进度外。

这是我通常做的事情,特别是如果结果是BitmapdoInBackground返回并由onPostExecute处理后的值在设置完成后不会设置为null,并且以这种方式偷偷摸摸地“泄漏”Bitmaps(由内存中保存的位图引起的内存错误)完成/完成AsyncTasks)。

答案 1 :(得分:1)

我认为你是对的,类型参数Params的唯一用法是Params...,这意味着它真的是Params[]。但是现在API只适用于数组类型,它错过了很多非数组类型。

varargs的唯一优势是在呼叫站点,但它也不多 -

Google的版本:

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

您的版本:

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