Назначение параметров varargs AsyncTask

Каковы причины, по которым Google использует varargs для параметров в AsyncTask ? Например, методы 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 сделал правильный выбор? Но, как я вижу, вас либо интересует список параметров одного и того же типа , либо вам нужны разные типы параметров. 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); } } 

Я не вижу, когда это может быть практическим. Но я уверен, что мне не хватает чего-то курии, о которой мне нужно знать. 🙂

Solutions Collecting From Web of "Назначение параметров varargs AsyncTask"

Я думаю, что аргументы vararg просто делают его более удобным, когда вы вызываете для выполнения AsyncTask .

Пока нам интересно, почему AsyncTask был спроектирован так: 🙂

На мой взгляд, шаблоны Param и Result не были бы действительно необходимы для достижения того же.

Когда вы пишете свою собственную AsyncTask , вы подклассифицируете ее. Вместо объявления реальных типов для Param и Result вы также можете добавить конечные поля в свой подкласс (Params) и добавить изменяемые поля в ваш подкласс (Result). Например:

 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 , не установлено onPostExecute null после того, как все установлено и выполнено, и оно скрытно «утечки» Bitmaps таким образом (ошибки памяти, вызванные растровыми изображениями, AsyncTasks в памяти, завершенными / завершенными AsyncTasks ).

Я думаю, что вы правы, единственное использование параметра типа Params находится в Params... , что подразумевает, что здесь действительно нужны Params[] . Однако теперь API работает только с типами массивов, он пропускает множество типов без массивов.

Единственное преимущество varargs – на сайте вызова, но это не так много –

Версия Google:

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

Ваша версия:

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