AsyncTask varargs 参数的用途

2022-09-03 16:06:38

Google 在 AsyncTask 中使用参数的原因是什么?例如,execute()doInBackground()publishProgress() 方法都使用这种表示法。varargs[Type]...

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


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

  1. 没有参数(简单):参数就是这样。(方法不能使用它...所以这是非常安全的。ParamsVoid

  2. 一个参数:在这里,至少我感觉有必要在方法的开头进行检查。例如,下面是一个任务,它接收并生成类型的结果:doInBackground()IntegerDouble

    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...


那么,如果我们完全删除,问题是什么?下面是这些方法的子集: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);
    }
}

我看不出它什么时候可以有任何实际用途。但我确信我错过了一些我需要知道的教廷。:)


答案 1

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

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

在我看来,和模板对于完成相同的任务并不是真正必要的。ParamResult

当你写你自己的,你子类化它。与其声明 和 的实际类型,不如将最终字段添加到子类 (Params) 中,并将可修改字段添加到子类 (Result) 中。例如:AsyncTaskParamResult

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

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

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


答案 2

我认为你是对的,type参数的唯一用法是 in ,这意味着它真的是这里想要的。但是,现在API仅适用于数组类型,它缺少大量非数组类型。ParamsParams...Params[]

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

谷歌的版本:

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

您的版本:

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

推荐