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 个泛型用于指定哪些类型转到 AsyncTask
的 doInBackground()
、onProgressUpdate()
和 onPostExecute()
方法。这允许您指示 AsyncTask
处理哪些特定类型的对象以进行处理 (Params
),用于进度更新 (Progress
) 并作为最终结果获取 (Result
).它使用 ...
的原因是由于可变参数:您可以在 API 中传递多个参数和进度报告。 Void
被使用,因为它是一个适当的对象,表示缺少真实对象(即装箱)。
我认为这里令人困惑的部分是泛型为某些方法定义了参数类型,同时为另一个方法定义了 return 类型。而且我们从不直接调用我们的 AsyncTask 覆盖的方法,而是通过我们调用的其他方法传递参数。许多示例使用 <Void, Void, Integer>
也无济于事,其中无法区分第一种和第二种类型。
这就是为什么除了其他答案之外,我还想加入一些带注释的示例代码。
请注意,当忽略可变参数时:
onPostExecute(ResultClass result)
的参数类型与ResultClass doInBackground(BackgroundParameterClass... parameters)
的return类型相同
publishProgress(ProgressClass progress)
的参数类型与onProgressUpdate(ProgressClass... values)
的参数类型相同
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());
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 个泛型用于指定哪些类型转到 AsyncTask
的 doInBackground()
、onProgressUpdate()
和 onPostExecute()
方法。这允许您指示 AsyncTask
处理哪些特定类型的对象以进行处理 (Params
),用于进度更新 (Progress
) 并作为最终结果获取 (Result
).它使用 ...
的原因是由于可变参数:您可以在 API 中传递多个参数和进度报告。 Void
被使用,因为它是一个适当的对象,表示缺少真实对象(即装箱)。
我认为这里令人困惑的部分是泛型为某些方法定义了参数类型,同时为另一个方法定义了 return 类型。而且我们从不直接调用我们的 AsyncTask 覆盖的方法,而是通过我们调用的其他方法传递参数。许多示例使用 <Void, Void, Integer>
也无济于事,其中无法区分第一种和第二种类型。
这就是为什么除了其他答案之外,我还想加入一些带注释的示例代码。
请注意,当忽略可变参数时:
onPostExecute(ResultClass result)
的参数类型与ResultClass doInBackground(BackgroundParameterClass... parameters)
的return类型相同
publishProgress(ProgressClass progress)
的参数类型与onProgressUpdate(ProgressClass... values)
的参数类型相同
的参数类型相同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());