未来与异步
Future and asynchronism
我使用外部 api(ESRI API 用于 Android),其中我有一个循环 return class 未来
...
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();
}
...
是否可以启动所有 queryFeaturesAsync 并在 for 循环后异步获取全局结果(result1 + result2 + 等等)?
最好的方法是什么?承诺?线程池执行器 ?
感谢您的帮助
我认为里面的方法 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
设为匿名 class 以缩短示例。在生产中它必须是静态的 class.
如果我使用 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 的解决方案吗?
感谢您的回复
我使用外部 api(ESRI API 用于 Android),其中我有一个循环 return class 未来
...
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();
}
...
是否可以启动所有 queryFeaturesAsync 并在 for 循环后异步获取全局结果(result1 + result2 + 等等)? 最好的方法是什么?承诺?线程池执行器 ?
感谢您的帮助
我认为里面的方法 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
设为匿名 class 以缩短示例。在生产中它必须是静态的 class.
如果我使用 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 的解决方案吗?
感谢您的回复