Java AsyncTask变量参数的用途

Java AsyncTask变量参数的用途,java,android,android-asynctask,Java,Android,Android Asynctask,Google使用varargs作为中的参数的原因是什么?例如,方法和都使用[Type]…符号 我认为这会使它“更难”使用,所以它们一定有一些我忽略的好理由 所以,我们要么没有参数,要么有一个或多个参数。让我们把它分解一下: 无参数(简单):Params参数为Void,仅此而已。(这些方法无法使用它……因此这相当安全。) 一个参数:至少在这里,我觉得有必要在doInBackground()方法的开头进行检查。例如,这里有一个任务接收一个整数,并生成一个类型为Double的结果: public D

Google使用
varargs
作为中的参数的原因是什么?例如,方法和都使用
[Type]…
符号

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


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

  • 无参数(简单):
    Params
    参数为
    Void
    ,仅此而已。(这些方法无法使用它……因此这相当安全。)

  • 一个参数:至少在这里,我觉得有必要在
    doInBackground()方法的开头进行检查。例如,这里有一个任务接收一个
    整数
    ,并生成一个类型为
    Double
    的结果:

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


  • 那么,如果我们完全删除
    varargs
    ,会有什么问题呢?以下是这些方法的子集:

    class AsyncTask<Param, Progress, Result> {
    
        abstract Result doInBackground(Param param);
        void publishProgress(Progress progress) { ... }
    }
    

    我看不出它什么时候有什么实际用途。但我肯定我遗漏了一些我需要知道的库里亚

    我想你是对的,类型参数
    Params
    的唯一用法是在
    Params…
    中,这意味着这里真正需要的是
    Params[]
    。然而,现在API只处理数组类型,它遗漏了很多非数组类型

    varargs的唯一优势是在调用站点,但也不多-

    谷歌版本:

    AsyncTask<String> task = ...
    task.execute("a", "b");
    
    AsyncTask任务=。。。
    任务。执行(“a”、“b”);
    
    您的版本:

    AsyncTask<List<String>> task = ...
    task.execute(Arrays.asList("a", "b"));
    
    AsyncTask任务=。。。
    task.execute(Arrays.asList(“a”、“b”));
    
    我认为当您调用以执行
    AsyncTask任务时,vararg参数只会使它更方便一些

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

    在我看来,
    Param
    Result
    模板对于完成同样的任务并不是真正必要的

    当您编写自己的
    AsyncTask
    时,您可以将其子类化。与其声明
    Param
    Result
    的实际类型,不如向子类(Params)添加最终字段,并向子类(Result)添加可修改字段。例如:

    公共类MyAsyncTask扩展了AsyncTask{
    //输入参数
    私人最终int参数1;
    参数2中的私有最终字符串;
    //输出结果
    私有位图结果位图;
    公共MyAsyncTask(int参数1,字符串参数2){
    inParam1=param1;
    inParam2=param2;
    }
    @凌驾
    受保护的void doInBackground(){
    //使用param1和param2作为后台进程的输入。
    ...
    ...
    //完成:分配给结果
    结果比特图=。。。。;
    } 
    @凌驾
    受保护的void onPostExecute(){
    //将结果发送到用户界面。
    …结果位图。。。
    ...
    resultBitmap=null;
    }
    }
    
    不需要仿制药,也许除了显示进展


    这是我通常做的,尤其是如果结果是
    位图
    doInBackground
    返回并由
    onPostExecute
    处理的值在所有设置和完成后不会设置为null,它会以这种方式偷偷地“泄漏”
    位图
    (由已完成/已完成的
    异步任务保存在内存中的位图导致的内存错误
    ).

    可能重复的问题为什么这个问题与那个问题重复?这是一个我质疑的特定界面。为什么开发人员使用varargs来解决这个特定问题。我想我已经说得很清楚了,我知道它是什么,并且在适当的时候使用它:)“我正在质疑的是一个特定的接口”--您的参数中没有任何与
    AsyncTask
    相关的特定内容。你可能会抱怨在
    餐厅
    课堂上使用varargs。如果您的问题集中在varargs对
    AsyncTask
    如何处理线程间通信的影响上,那么它可能不会重复。但是,就目前情况而言,IMHO,我引用的问题中给出的答案似乎也涵盖了这个问题。此外,“谷歌使用varargs作为参数的原因”是不可能回答的,除非我们能够说服Romain Guy(AsyncTask
    的原始作者)插话回答这个问题。在本例中,最接近为什么使用varargs的答案是为什么一般使用varargs,这在链接到的问题中有介绍。
    AsyncTask<List<String>> task = ...
    task.execute(Arrays.asList("a", "b"));
    
    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;
        }
    }