2013-03-06 114 views
13

Google使用varargs作为参数AsyncTask的原因是什么?例如,方法execute(),doInBackground()publishProgress()全部使用[Type]...表示法。AsyncTask可变参数参数的用途

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


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

  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...并没有真正类型安全的...)


所以,如果我们完全删除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); 
    } 
} 

我不明白的时候它可以是任何实际用途。但我确定我错过了一些我需要了解的curia。 :)

+0

可能重复[当你在Java中使用可变参数?](http://stackoverflow.com/questions/766559/when-do-you-use-varargs -in-java) – CommonsWare 2013-03-06 00:09:07

+1

为什么这个问题是这个问题的重复?这是我质疑的特定界面。为什么开发人员使用可变参数这个特定的问题。我以为我明确表示,我知道它是什么,我会在适当的时候使用它。:) – dacwe 2013-03-06 00:10:36

+0

“这是一个我正在质疑的具体界面” - 在你的论点中没有任何东西与任何特定的东西有关'AsyncTask'。您可能会抱怨使用带有“餐厅”类的可变参数。如果你的问题集中在可变参数的影响上,比如说AsyncTask处理线程之间的通信,那么它可能不是重复的。但是,恕我直言,在我引用的问题中提出的答案似乎也涵盖了这个问题。 – CommonsWare 2013-03-06 00:14:38

回答

1

,我认为你是对的,类型参数Params唯一的用法是在Params...,这意味着它真的是在这里希望Params[]。但是现在这个API只能用于数组类型,它会丢失大量的非数组类型。

可变参数的唯一好处是在调用点,但它不是太大或者 -

谷歌的版本:

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

您的版本:

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

我觉得可变参数的参数只是当您致电AsyncTask才更方便。

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

在我看来,在ParamResult模板也不会被真的有必要来完成相同的。

当你写你自己的AsyncTask,你继承它。而不是声明的实际类型ParamResult的,你可能也增加最终字段子类(PARAMS),并添加修改字段子类(结果)。例如:

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返回和处理由onPostExecute值都设置后未设置为空,做它鬼祟“泄漏” Bitmaps这种方式(由于通过完成保存在内存中的位图的内存错误/结束AsyncTasks)。