15

Googlevarargsが のパラメータに使用する理由は何AsyncTaskですか? たとえば、メソッドexecute()doInBackground()およびpublishProgress()すべては[Type]...表記法を使用します。

それが使いにくいと思うので、私が見落としていた正当な理由があるに違いありませんか?


したがって、パラメータがないか、1 つまたは複数のパラメータがあります。それを分解しましょう:

  1. パラメーターなし(簡単):ParamsパラメーターはVoidそれだけです。(メソッドはそれを使用できません...そのため、かなり安全です。)

  2. 1 つのパラメーター: ここでは、少なくとも、doInBackground()メソッドの開始時にチェックを行う必要があると感じています。たとえば、 を受け取ってIntegertype の結果を生成するタスクは次の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 はこれらのケースの 1 つだけに対処しました (型が異なると、ある種の共通インターフェイスが必要になります。多くの場合、最終的に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);
    }
}

いつ実用化されるかわかりません。しかし、私が知る必要のあるキュリアが欠けていると確信しています。:)

4

2 に答える 2

2

vararg引数を呼び出すと、を実行するときに少し便利になると思いますAsyncTask

なぜAsyncTaskがそのように設計されたのか疑問に思っている限り::-)

私の意見では、ParamResultテンプレートは同じことを達成するために実際には必要ではなかったでしょう。

あなたがあなた自身を書くとき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、すべてが設定および実行された後はnullに設定されず、Bitmapsこのようにこっそりと「リーク」します(completed / finishによってメモリに保持されたビットマップによって引き起こされるメモリエラーAsyncTasks)。

于 2013-03-06T15:01:23.343 に答える
1

私はあなたが正しいと思います、typeパラメータの唯一の使用法はParamsParams...あり、それはそれが本当にParams[]ここで望まれていることを意味します。ただし、APIは配列タイプでのみ機能するようになり、非配列タイプの多くを見逃しています。

varargsの唯一の利点は呼び出しサイトにありますが、それもそれほど多くはありません-

Googleのバージョン:

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

あなたのバージョン:

AsyncTask<List<String>> task = ...
task.execute(Arrays.asList("a", "b"));
于 2013-03-06T00:29:25.703 に答える