0

我使用 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();
...
}

或者

try {
                FeatureQueryResult result = future.get();


    }
    ...

是否可以在 for 循环之后以异步方式启动所有 queryFeaturesAsync 并获取全局结果(result1 + result2 + etc..)?最好的方法是什么?承诺?线程池执行器?

谢谢你的帮助

4

2 回答 2

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作为一个匿名类来缩短示例。在生产中,它必须是静态类。

于 2017-12-05T10:55:45.723 回答
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 的解决方案?

感谢您的回复

于 2017-12-06T09:07:14.977 回答