未来和异步

时间:2017-12-05 08:41:26

标签: android asynchronous futuretask esri-arc-engine

我使用extern api(适用于Android的ESRI API),我有一个循环,我将返回一个类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();


    }
    ...

是否可以在循环后异步启动所有queryFeaturesAsync并获取全局结果(result1 + result2 + etc ..)? 最好的方法是什么?承诺? ThreadPoolExecutor?

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

我认为方法queryFeaturesAsync()内部已经使用ThreadPoolService,并且使用ThreadPoolService来检索来自另一个ThreadPoolService的结果是过度的,恕我直言。

我建议您使用AsyncTask因为它是原生的Android SDK工具并且使用起来非常简单:

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

我将AsyncTask作为匿名类来缩短示例。在制作时,它必须是静态类。

答案 1 :(得分:0)

如果我使用CompletableFuture是最好的方法吗? 我不明白......

List<CompletableFuture<FeatureQueryResult>> futures = new ArrayList<>();                
for (Layer layer : layers) {
    FeatureTable gdbFeatureTable = ((FeatureLayer) layer).getFeatureTable();
    CompletableFuture<FeatureQueryResult>  completableFuture = new CompletableFuture<>();
    ListenableFuture<FeatureQueryResult> future = gdbFeatureTable.queryFeaturesAsync(query);
    future.addDoneListener(() -> {
                        FeatureQueryResult result = future.get();
                        completableFuture.complete(result);
    }
    futures.add(future);
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));

您是否有另一种具有completablefuture的解决方案?

感谢您的回复