2013-03-06 115 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)。