Eae
Eae

Reputation: 4321

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();
                }

An AsyncTask object is being created I understand. I see from docs parameters can be changed or defined as needed. I could use more explanation on exactly why the first two parameters would be declared as Void, Void. As well doInBackground params type is a Void...? Is there significance to the use of "..." for instance what might be the difference between plain "Void" and "Void...".

I look forward to any responses or comments. The code I am taking from the CollectAllTheStars Google Play Games Services Basic Samples.

Thank you.

Upvotes: 0

Views: 170

Answers (3)

Suau
Suau

Reputation: 4738

I believe the confusing part here is that the generics define the parameter type for some methods, as well as the return type for another method at the same time. And also we never call the methods overridden by our AsyncTask directly, instead the parameters are passed through by other methods we call. It doesn't help either that a lot of examples use <Void, Void, Integer>, where the first and second type can't be distinguished.

That's why I want to throw in some commented sample code in addition to the other answers.

Note that, when ignoring varargs:

  1. The parameter type of onPostExecute(ResultClass result) is the same as the return type of ResultClass doInBackground(BackgroundParameterClass... parameters)
  2. The parameter type of publishProgress(ProgressClass progress) is the same as the parameter type of onProgressUpdate(ProgressClass... values)
  3. The parameter type of execute(BackgroundParameterClass backgroundParameter); is the same as the parameter type of 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
        }
    }
    

Then get the MyAsyncTask going by calling

new MyAsyncTask().execute(new BackgroundParameterClass());

Upvotes: 1

Larry Schiefer
Larry Schiefer

Reputation: 15775

The 3 generics are used to specify what types go to the doInBackground(), onProgressUpdate() and onPostExecute() methods of the AsyncTask. This allows you to indicate what specific types of objects the AsyncTask deals with for processing (Params), uses for progress updates (Progress) and gets as a final result (Result). The reason it uses ... is due to variable arguments: you can pass more than one parameter and progress report in the APIs. Void is used as it is a proper object indicating the lack of a real object (i.e. boxing.)

Upvotes: 4

Willis
Willis

Reputation: 5336

Three dots (...) in Java denotes a Vararg, which means you can pass zero or more objects (as an array) into your method (or AsyncTask or whatever). They are explained really well here:

Java, 3 dots in parameters

Upvotes: 1

Related Questions