【问题标题】:Looking for PendingResult await() equivalent in New Places SDK Client在 New Places SDK 客户端中寻找 PendingResult await() 等效项
【发布时间】:2019-01-30 11:50:20
【问题描述】:

背景:我有一个包含不同地点 ID 的字符串列表。一旦用户选择了他的位置,我就会执行一个循环并确定列表中的每个位置(我从位置 ID 获取位置)是否在他选择的位置附近。我能够使用旧的 Places SDK 实现这一点,但无法将其迁移到新的 SDK,因为新的 SDK 似乎没有 await() 等效项。

这是我的旧代码:

   // 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 类,其中 await() 作为方法之一。此 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-places-api google-places


    【解决方案1】:

    据我所知,Google's Task API 可以等待任何 Google API 任务。

    例如,findAutocompletePredictions 返回一个Task&lt;&gt; 对象。您可以将该任务传递给Tasks.await,而不是添加onCompleteListener

    而不是这种非阻塞方式:

    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&lt;T&gt;,但是你可以使用它。

    【讨论】:

    • 感谢@Gene 的提示!!
    【解决方案2】:

    我通过使用任务类解决了这个问题。见下文:

     for (int position = 0; position < results.size(); position++) {
                // Get the placeID 
                String placeId = results.get(position).getAddress();
    
                // 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();
    
                // create a FetchPlaceResponse task
                Task<FetchPlaceResponse> task = placesClient.fetchPlace(request);
    
                try {
                    FetchPlaceResponse response = Tasks.await(task);
                    Place place = response.getPlace();
    
                    // Get the latitude and longitude for the specific place
                    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);
    

    这两个代码会要求系统等待响应..

    任务task = placesClient.fetchPlace(request);

    FetchPlaceResponse 响应 = Tasks.await(task);

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多