繁体   English   中英

从使用 Retrofit 2 的方法返回字符串 java Android

[英]Return string from method using Retrofit 2 for java Android

我正在尝试查询谷歌地图 api 以获取基于 lat/lng 的位置的 placeId。 我遇到的问题是我的代码在 API 响应之前移动到 return 语句,因此返回字符串是 null 而不是来自 api 的 placeId。 有人可以帮我弄清楚我错过了什么吗?
已编辑
我已更改 getPlaceId 方法以返回 null 并简单地将响应中的 getPlaceId 分配给公共变量。 我从 API 获取数据,但看起来好像 json 没有被解析,因此变量仍然是 null。

使用 retrofit 的 getPlaceId 方法
已编辑

String lat = "39.748378", lng = "-91.857558", placeId;

 Map<String, String> query = new HashMap<>();
    query.put("latlng", lat+","+lng);
    query.put("key","API_KEY");

public void getPlaceId(final Map<String, String> query) {
    String BASE_URL = "https://maps.googleapis.com/maps/";
    Retrofit retrofit;

    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(logging)
            .build();

    retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();
    PlacesInterface service = retrofit.create(PlacesInterface.class);
    Call<PlacesFoo> call = service.loadPlace(query);
    call.enqueue(new Callback<PlacesFoo>() {
      @Override
      public void onResponse(Call<PlacesFoo> call, Response<PlacesFoo> response) {
        if(response.isSuccessful()) {
          Log.e("getPlaceId", " Valid Response: " + response.body());
          placeId = response.body().getResults().get(0).getPlaceId();
        } else {
          System.out.println(response.errorBody());
        }
      }

      @Override
      public void onFailure(Call<PlacesFoo> call, Throwable t) {
        t.printStackTrace();
        Log.e("getPlaceId", " Error Response: " + t);
      }
    });
    //return placeId;
  }

API 接口

public interface PlacesInterface {
   
    // https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&key=API_KEY
    @GET("api/geocode/json")
    Call<PlacesFoo> loadPlace(@QueryMap Map<String, String> options);

}

POJO for API 回复

public class PlacesFoo {

    @SerializedName("plus_code")
    @Expose
    private PlusCode plusCode;
    @SerializedName("results")
    @Expose
    private List<Result> results = null;
    @SerializedName("status")
    @Expose
    private String status;

    public PlusCode getPlusCode() {
        return plusCode;
    }

    public void setPlusCode(PlusCode plusCode) {
        this.plusCode = plusCode;
    }

    public List<Result> getResults() {
        return results;
    }

    public void setResults(List<Result> results) {
        this.results = results;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public class AddressComponent {

        @SerializedName("long_name")
        @Expose
        private String longName;
        @SerializedName("short_name")
        @Expose
        private String shortName;
        @SerializedName("types")
        @Expose
        private List<String> types = null;

        public String getLongName() {
            return longName;
        }

        public void setLongName(String longName) {
            this.longName = longName;
        }

        public String getShortName() {
            return shortName;
        }

        public void setShortName(String shortName) {
            this.shortName = shortName;
        }

        public List<String> getTypes() {
            return types;
        }

        public void setTypes(List<String> types) {
            this.types = types;
        }

    }

    public class Bounds {

        @SerializedName("northeast")
        @Expose
        private Northeast_ northeast;
        @SerializedName("southwest")
        @Expose
        private Southwest_ southwest;

        public Northeast_ getNortheast() {
            return northeast;
        }

        public void setNortheast(Northeast_ northeast) {
            this.northeast = northeast;
        }

        public Southwest_ getSouthwest() {
            return southwest;
        }

        public void setSouthwest(Southwest_ southwest) {
            this.southwest = southwest;
        }

    }

    public class Geometry {

        @SerializedName("location")
        @Expose
        private Location location;
        @SerializedName("location_type")
        @Expose
        private String locationType;
        @SerializedName("viewport")
        @Expose
        private Viewport viewport;
        @SerializedName("bounds")
        @Expose
        private Bounds bounds;

        public Location getLocation() {
            return location;
        }

        public void setLocation(Location location) {
            this.location = location;
        }

        public String getLocationType() {
            return locationType;
        }

        public void setLocationType(String locationType) {
            this.locationType = locationType;
        }

        public Viewport getViewport() {
            return viewport;
        }

        public void setViewport(Viewport viewport) {
            this.viewport = viewport;
        }

        public Bounds getBounds() {
            return bounds;
        }

        public void setBounds(Bounds bounds) {
            this.bounds = bounds;
        }

    }

    public class Location {

        @SerializedName("lat")
        @Expose
        private Double lat;
        @SerializedName("lng")
        @Expose
        private Double lng;

        public Double getLat() {
            return lat;
        }

        public void setLat(Double lat) {
            this.lat = lat;
        }

        public Double getLng() {
            return lng;
        }

        public void setLng(Double lng) {
            this.lng = lng;
        }

    }

    public class Northeast {

        @SerializedName("lat")
        @Expose
        private Double lat;
        @SerializedName("lng")
        @Expose
        private Double lng;

        public Double getLat() {
            return lat;
        }

        public void setLat(Double lat) {
            this.lat = lat;
        }

        public Double getLng() {
            return lng;
        }

        public void setLng(Double lng) {
            this.lng = lng;
        }

    }

    public class Northeast_ {

        @SerializedName("lat")
        @Expose
        private Double lat;
        @SerializedName("lng")
        @Expose
        private Double lng;

        public Double getLat() {
            return lat;
        }

        public void setLat(Double lat) {
            this.lat = lat;
        }

        public Double getLng() {
            return lng;
        }

        public void setLng(Double lng) {
            this.lng = lng;
        }

    }

    public class PlusCode {

        @SerializedName("compound_code")
        @Expose
        private String compoundCode;
        @SerializedName("global_code")
        @Expose
        private String globalCode;

        public String getCompoundCode() {
            return compoundCode;
        }

        public void setCompoundCode(String compoundCode) {
            this.compoundCode = compoundCode;
        }

        public String getGlobalCode() {
            return globalCode;
        }

        public void setGlobalCode(String globalCode) {
            this.globalCode = globalCode;
        }

    }

    public class PlusCode_ {

        @SerializedName("compound_code")
        @Expose
        private String compoundCode;
        @SerializedName("global_code")
        @Expose
        private String globalCode;

        public String getCompoundCode() {
            return compoundCode;
        }

        public void setCompoundCode(String compoundCode) {
            this.compoundCode = compoundCode;
        }

        public String getGlobalCode() {
            return globalCode;
        }

        public void setGlobalCode(String globalCode) {
            this.globalCode = globalCode;
        }

    }

    public class Result {

        @SerializedName("address_components")
        @Expose
        private List<AddressComponent> addressComponents = null;
        @SerializedName("formatted_address")
        @Expose
        private String formattedAddress;
        @SerializedName("geometry")
        @Expose
        private Geometry geometry;
        @SerializedName("place_id")
        @Expose
        private String placeId;
        @SerializedName("plus_code")
        @Expose
        private PlusCode_ plusCode;
        @SerializedName("types")
        @Expose
        private List<String> types = null;

        public List<AddressComponent> getAddressComponents() {
            return addressComponents;
        }

        public void setAddressComponents(List<AddressComponent> addressComponents) {
            this.addressComponents = addressComponents;
        }

        public String getFormattedAddress() {
            return formattedAddress;
        }

        public void setFormattedAddress(String formattedAddress) {
            this.formattedAddress = formattedAddress;
        }

        public Geometry getGeometry() {
            return geometry;
        }

        public void setGeometry(Geometry geometry) {
            this.geometry = geometry;
        }

        public String getPlaceId() {
            return placeId;
        }

        public void setPlaceId(String placeId) {
            this.placeId = placeId;
        }

        public PlusCode_ getPlusCode() {
            return plusCode;
        }

        public void setPlusCode(PlusCode_ plusCode) {
            this.plusCode = plusCode;
        }

        public List<String> getTypes() {
            return types;
        }

        public void setTypes(List<String> types) {
            this.types = types;
        }

    }

    public class Southwest {

        @SerializedName("lat")
        @Expose
        private Double lat;
        @SerializedName("lng")
        @Expose
        private Double lng;

        public Double getLat() {
            return lat;
        }

        public void setLat(Double lat) {
            this.lat = lat;
        }

        public Double getLng() {
            return lng;
        }

        public void setLng(Double lng) {
            this.lng = lng;
        }

    }

    public class Southwest_ {

        @SerializedName("lat")
        @Expose
        private Double lat;
        @SerializedName("lng")
        @Expose
        private Double lng;

        public Double getLat() {
            return lat;
        }

        public void setLat(Double lat) {
            this.lat = lat;
        }

        public Double getLng() {
            return lng;
        }

        public void setLng(Double lng) {
            this.lng = lng;
        }

    }

    public class Viewport {

        @SerializedName("northeast")
        @Expose
        private Northeast northeast;
        @SerializedName("southwest")
        @Expose
        private Southwest southwest;

        public Northeast getNortheast() {
            return northeast;
        }

        public void setNortheast(Northeast northeast) {
            this.northeast = northeast;
        }

        public Southwest getSouthwest() {
            return southwest;
        }

        public void setSouthwest(Southwest southwest) {
            this.southwest = southwest;
        }
    }
}

Retrofit 支持同步和异步请求执行。 用户通过为服务方法设置返回类型(同步)或非(异步)来定义具体执行。

编辑您需要通过接口传递异步调用的结果

 public interface MyCallback {
    void onSuccess(String placeId);
    void onError(String error);
}

你的电话会像

getPlaceId(new MyCallback() {
        @Override
        public void onSuccess(String placeId) {
            // here you get place Id you can do your work with id
            Log.e("PlaceID",placeId);
        }

        @Override
        public void onError(String error) {
            // in case of error occurred
        }
    });

Retrofit 来电

  private void getPlaceId(MyCallback myCallback) {
    .....
    .....
    PlacesInterface service = retrofit.create(PlacesInterface .class);
    Call<PlacesFoo> call = service.loadPlace(query);
    call.enqueue(new Callback<PlacesFoo>() {
        @Override
        public void onResponse(@NotNull Call<PlacesFoo> call, @NotNull Response<PlacesFoo> response) {
            if (response.isSuccessful()) {
                String placeId = response.body().getResults().get(0).getPlaceId();
                myCallback.onSuccess(placeId);

            } else {
                if (response.errorBody() != null) {
                    myCallback.onError(response.errorBody().toString());
                }

            }
        }

        @Override
        public void onFailure(@NotNull Call<PlacesFoo> call, @NotNull Throwable t) {
            t.printStackTrace();
            myCallback.onError(t.getLocalizedMessage());
        }
    });

}

要知道异步同步请求之间的区别检查这个

首先创建如下界面:

public interface OnPlaceIdFoundListener {
    void onPlaceIdFound(String placeId);
}

其次,您应该更改 getPlaceId 方法的签名和主体,如下所示(请参阅“@@here@@:!!!!”符号):

public void getPlaceId(final Map<String, String> query, OnPlaceIdFoundListener callback) {
    String BASE_URL = "https://maps.googleapis.com/maps/";
    Retrofit retrofit;

    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(logging)
            .build();

    retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();
    PlacesInterface service = retrofit.create(PlacesInterface.class);
    Call<PlacesFoo> call = service.loadPlace(query);
    call.enqueue(new Callback<PlacesFoo>() {
        @Override
        public void onResponse(Call<PlacesFoo> call, Response<PlacesFoo> response) {
            if(response.isSuccessful()) {
                Log.e("getPlaceId", " Valid Response: " + response.body());
                String placeId = response.body().getResults().get(0).getPlaceId();
                callback.onPlaceIdFound(placeId); // @@here@@!!!!!
            } else {
                System.out.println(response.errorBody());
                callback.onPlaceIdFound(""); // @@here@@!!!!!

            }
        }

        @Override
        public void onFailure(Call<PlacesFoo> call, Throwable t) {
            t.printStackTrace();
            callback.onPlaceIdFound(""); // @@here@@!!!!!
            Log.e("getPlaceId", " Error Response: " + t);
        }
    });
    //return placeId;
}

然后用你的方法。

getPlaceId(query, new OnPlaceIdFoundListener() {
    @Override
    public void onPlaceIdFound(String placeId) {
         Log.d("TAG", "place id is found = "+ placeId);
    }
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM