背景:我有一个字符串列表,其中包含不同的地点 ID。一旦用户选择了他的位置,我就会执行一个循环并确定列表中的每个地点(我从地点 ID 获取位置)是否靠近他选择的位置。我能够使用旧的 Places SDK 实现此功能,但无法将其迁移到新的 SDK,因为新的 SDK 似乎没有等效的 wait()。
这是我的旧代码:
// contains a list of Offices. Has method getId() which contains the Place ID from Google.
List<Office> results = obtained from the database...
// go thru each Location and find those near the user's location
for (int i = 0; i < results.size(); i++) {
// Get the place from the placeID
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi.
getPlaceById(mGoogleApiClient, results.get(i).getId());
// wait for the result to come out (NEED EQUIVALENT IN NEW PLACES SDK)
PlaceBuffer places = placeResult.await();
// Get the latitude and longitude for the specific Location
LatLng latLng = places.get(0).getLatLng();
// Set the location object for the specific business
Location A = new Location("Business");
A.setLatitude(latLng.latitude);
A.setLongitude(latLng.longitude);
// get the distance of the business from the user's selected location
float distance = A.distanceTo(mSelectedLocation);
// if the distance is less than 50m away
if (distance < 50) { ... do something in code}
正如您在上面的代码中所看到的,旧的 PLACES SDK API 有一个 PendingResult 类,其中的方法之一是 wait()。根据文档,此await()会阻塞,直到任务完成。总而言之,在从 getPlaceById 获得结果之前,代码不会继续执行。
我按照文档迁移到新的 Places SDK,但遇到了问题。这是我根据 Google 文档迁移的新代码:https://developers.google.com/places/android-sdk/client-migration#fetch_a_place_by_id
for (int i = 0; i < results.size(); i++) {
// Get the place Id
String placeId = results.get(position).getId();
// Specify the fields to return.
List<Place.Field> placeFields = Arrays.asList(Place.Field.ID, Place.Field.NAME,
Place.Field.LAT_LNG, Place.Field.ADDRESS);
// Construct a request object, passing the place ID and fields array.
FetchPlaceRequest request = FetchPlaceRequest.builder(placeId, placeFields)
.build();
// Add a listener to handle the response.
placesClient.fetchPlace(request).addOnSuccessListener((response) -> {
Place place = response.getPlace();
// Get the latitude and longitude for the specific location
LatLng latLng = place.getLatLng();
// Set the location object for the specific business
Location A = new Location("Business");
A.setLatitude(latLng.latitude);
A.setLongitude(latLng.longitude);
// get the distance of the business from the selected location
float distance = A.distanceTo(mSelectedLocation);
// if the distance is less than 50m away
if (distance < 50) { ... do something in code}
这里的关键问题似乎是在旧代码中,await() 会阻塞代码直到成功,因此 for 循环不会处理。然而 OnSuccessListener 的情况并非如此。因此,对于新迁移的代码,即使 fetchPlace 尚未完成获取每次迭代的结果,for 循环也会继续并完成循环。因此,代码已被破坏,无法获得所需的结果。
有没有办法阻止代码移动直到 fetchPlace 完成?!
最佳答案
任何 Google API 任务都可以通过 Google's Task API 等待据我所知。
例如,findAutocompletePredictions
返回 Task<>
目的。而不是添加 onCompleteListener
,您可以将该任务传递给 Tasks.await
.
而不是这种非阻塞方式:
OnCompleteListener<T> onCompleteListener=
new OnCompleteListener<T> {...}
placesClient.findAutocompletePredictions(f)
.addOnCompleteListener(onCompleteListener);
您可以将其转发至Tasks.await()
并使 API 调用阻塞:
T results = null;
try {
// No timeout
results = Tasks.await(placesClient.findAutocompletePredictions(f));
// Optionally, with a 30 second timeout:
results = Tasks.await(
placesClient.findAutocompletePredictions(f), 30, TimeUnit.SECONDS);
} catch (ExecutionException e) {
// Catch me
} catch (TimeoutException e) {
// Catch me, only needed when a timeout is set
} catch (InterruptedException e) {
// Catch me
}
if (results != null) {
// Do something
} else {
// Do another thing
}
基本上,不是得到 PendingResult
默认情况下,您现在获得 Task<T>
不过您可以使用。
关于google-places-api - 在 New Places SDK 客户端中查找 PendingResult wait() 等效项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54439987/