androidasynchronousfuturetaskesri-arc-engine

Future and asynchronism


I use a extern api (ESRI API for Android) where I have a loop for which me return a class Future

...
for (Layer layer : layers) {

// ListenableFuture extends Future<V>
final ListenableFuture<FeatureQueryResult> future= gdbFeatureTable.queryFeaturesAsync(query);

future.addDoneListener(() -> {
                try {
                    FeatureQueryResult result = future.get();
...
}

OR

try {
                FeatureQueryResult result = future.get();


    }
    ...

Is it possible to launch all queryFeaturesAsync and obtain the global result (result1 + result2 + etc..) with asynchronously after the loop for ? What's the best way ? promises? ThreadPoolExecutor ?

Thanks for your help


Solution

  • I think method queryFeaturesAsync() inside already uses ThreadPoolService, and using ThreadPoolService to retreive result from another ThreadPoolService is overkill, IMHO.

    I would recomend you to use AsyncTask becuse it is native Android SDK tool and very simple to use:

    AsyncTask<ListenableFuture<FeatureQueryResult>, Integer, List<FeatureQueryResult>> task =
            new AsyncTask<ListenableFuture<FeatureQueryResult>, Integer, List<FeatureQueryResult>>() {
        @Override
        protected List<FeatureQueryResult> doInBackground(ListenableFuture<FeatureQueryResult>[] futures) {
            int counter = 0;
            List<FeatureQueryResult> results = new ArrayList<>();
            for (ListenableFuture<FeatureQueryResult> future : futures) {
                try {
                    results.add(future.get());
                    publishProgress(++counter); // Optional feature
                } catch (ExecutionException | InterruptedException e) {
                    Log.w("Huh?", "Interrupted!");
                }
            }
            return results;
        }
    
        @Override
        protected void onProgressUpdate(Integer... values) {
            notifyMainThreadAboutProgress(values[0]); // Optional feature
        }
    
        @Override
        protected void onPostExecute(List<FeatureQueryResult> featureQueryResults) {
            doSomethingWithResultsInMainThread(featureQueryResults);
        }
    };
    
    ListenableFuture<FeatureQueryResult> future1 = gdbFeatureTable.queryFeaturesAsync(query);
    ListenableFuture<FeatureQueryResult> future2 = gdbFeatureTable.queryFeaturesAsync(another_query);
    ListenableFuture<FeatureQueryResult> future3 = gdbFeatureTable.queryFeaturesAsync(yet_another_query);
    
    task.execute(future1, future2, future3);
    

    I made AsyncTask as an anonymous class for shortening of example. On production it must be static class.