Java 中的 AsyncTask 参数和“...”的使用

AsyncTask parameters and use of "..." in Java

                    void saveSnapshot(final SnapshotMetadata snapshotMetadata) {
                    AsyncTask<Void, Void, Snapshots.OpenSnapshotResult> task =
                            new AsyncTask<Void, Void, Snapshots.OpenSnapshotResult>() {
                                @Override
                                protected Snapshots.OpenSnapshotResult doInBackground(Void... params) {
                                    if (snapshotMetadata == null) {
                                        Log.i(TAG, "Calling open with " + currentSaveName);
                                        return Games.Snapshots.open(mGoogleApiClient, currentSaveName, true)
                                                .await();
                                    }
                                    else {
                                        Log.i(TAG, "Calling open with " + snapshotMetadata);
                                        return Games.Snapshots.open(mGoogleApiClient, snapshotMetadata)
                                                .await();
                                    }
                                }

                                @Override
                                protected void onPostExecute(Snapshots.OpenSnapshotResult result) {
                                    Snapshot toWrite = processSnapshotOpenResult(RC_SAVE_SNAPSHOT, result, 0);
                                    if (toWrite != null) {
                                        Log.i(TAG, writeSnapshot(toWrite));
                                    }
                                    else {
                                        Log.e(TAG, "Error opening snapshot: " + result.toString());
                                    }
                                }
                            };

                    task.execute();
                }

我知道正在创建一个 AsyncTask 对象。我从文档中看到可以根据需要更改或定义参数。我可以用更多的解释来解释为什么前两个参数会被声明为 Void,Void。 doInBackground 参数类型也是 Void ...?使用“...”是否有意义,例如普通 "Void" 和 "Void...".

之间的区别

我期待任何回复或评论。我从 CollectAllTheStars Google Play 游戏服务基本示例中获取的代码。

谢谢。

Java 中的三个点 (...) 表示 Vararg,这意味着您可以将零个或多个对象(作为数组)传递到您的方法(或 AsyncTask 或其他)。它们在这里得到了很好的解释:

Java, 3 dots in parameters

这 3 个泛型用于指定哪些类型转到 AsyncTaskdoInBackground()onProgressUpdate()onPostExecute() 方法。这允许您指示 AsyncTask 处理哪些特定类型的对象以进行处理 (Params),用于进度更新 (Progress) 并作为最终结果获取 (Result).它使用 ... 的原因是由于可变参数:您可以在 API 中传递多个参数和进度报告。 Void 被使用,因为它是一个适当的对象,表示缺少真实对象(即装箱)。

我认为这里令人困惑的部分是泛型为某些方法定义了参数类型,同时为另一个方法定义了 return 类型。而且我们从不直接调用我们的 AsyncTask 覆盖的方法,而是通过我们调用的其他方法传递参数。许多示例使用 <Void, Void, Integer> 也无济于事,其中无法区分第一种和第二种类型。

这就是为什么除了其他答案之外,我还想加入一些带注释的示例代码。

请注意,当忽略可变参数时:

  1. onPostExecute(ResultClass result)的参数类型与ResultClass doInBackground(BackgroundParameterClass... parameters)
  2. 的return类型相同
  3. publishProgress(ProgressClass progress)的参数类型与onProgressUpdate(ProgressClass... values)的参数类型相同
  4. execute(BackgroundParameterClass backgroundParameter);的参数类型与doInBackground(BackgroundParameterClass... params)

    的参数类型相同
    private static class BackgroundParameterClass {};
    private static class ProgressClass {};
    private static class ResultClass {};
    
    /**
     * This AsyncTask could for example download a image from a web server
     */
    private static class MyAsyncTask extends AsyncTask<BackgroundParameterClass, ProgressClass, ResultClass> {
    
        @Override
        protected void onPreExecute() {
            // this is called on the UI thread
            // do anything you need to do before the background word start
            // e.g. disable the download button
        }
    
        @Override
        protected ResultClass doInBackground(BackgroundParameterClass... params) {
            // Do some background work here, for example in a loop
            // call then publishProgress(B... values)
            // e.g download the image from a server
            for (int index = 0; index < 10; index++) {
                // download the image in chunks
                ProgressClass progress = new ProgressClass();
                publishProgress(progress);
            }
            ResultClass result = new ResultClass();
            return result;
        }
    
        @Override
        protected void onProgressUpdate(ProgressClass... values) {
            // this is called on the UI thread
            // e.g. update a loading bar
        }
    
        @Override
        protected void onPostExecute(ResultClass resultClass) {
            // this is called on the UI thread
            // e.g. display the image in your UI
        }
    }
    

然后通过调用

让 MyAsyncTask 运行
new MyAsyncTask().execute(new BackgroundParameterClass());