使用 Retrofit 2 在 Java Android 中从方法返回字符串。

huangapple go评论98阅读模式
英文:

Return string from method using Retrofit 2 for java Android

问题

以下是您提供的代码的翻译部分:

  1. 我正在尝试查询 Google 地图 API根据纬度/经度获取位置的 placeId我遇到的问题是我的代码在 API 响应之前就移动到了返回语句因此返回的字符串为空而不是来自 API placeId有人能帮我找出我漏掉了什么吗
  2. <BR>**已编辑**<br>
  3. 我已将 getPlaceId 方法更改为返回 null并将来自响应的 getPlaceId 分配给公共变量我从 API 获取了数据但似乎 JSON 没有被解析因此变量仍为 null
  4. 使用 Retrofit getPlaceId 方法 <BR>
  5. **已编辑**

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;

  1. HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
  2. logging.setLevel(HttpLoggingInterceptor.Level.BODY);
  3. OkHttpClient client = new OkHttpClient.Builder()
  4. .addInterceptor(logging)
  5. .build();
  6. retrofit = new Retrofit.Builder()
  7. .baseUrl(BASE_URL)
  8. .addConverterFactory(GsonConverterFactory.create())
  9. .client(client)
  10. .build();
  11. PlacesInterface service = retrofit.create(PlacesInterface.class);
  12. Call<PlacesFoo> call = service.loadPlace(query);
  13. call.enqueue(new Callback<PlacesFoo>() {
  14. @Override
  15. public void onResponse(Call<PlacesFoo> call, Response<PlacesFoo> response) {
  16. if (response.isSuccessful()) {
  17. Log.e("getPlaceId", " 有效的响应:" + response.body());
  18. placeId = response.body().getResults().get(0).getPlaceId();
  19. } else {
  20. System.out.println(response.errorBody());
  21. }
  22. }
  23. @Override
  24. public void onFailure(Call<PlacesFoo> call, Throwable t) {
  25. t.printStackTrace();
  26. Log.e("getPlaceId", " 错误的响应:" + t);
  27. }
  28. });
  29. //return placeId;

}

API 的接口

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

用于 API 响应的 POJO

  1. public class PlacesFoo {
  2. @SerializedName("plus_code")
  3. @Expose
  4. private PlusCode plusCode;
  5. @SerializedName("results")
  6. @Expose
  7. private List<Result> results = null;
  8. @SerializedName("status")
  9. @Expose
  10. private String status;
  11. // 其他代码部分...
  12. }

请注意,这只是您提供的代码的翻译部分。如果您有进一步的问题或需要更多帮助,请随时提问。

英文:

I'm attempting to query google maps api to get the placeId of a location based on lat/lng. The issue I'm having is the my code moves to the return statement before the API responds and as a result the return string is null instead of the placeId from the api. Can someone help me figure out what I'm missing?
<BR>EDITED<br>
I have changed the getPlaceId method to return null and simply assign the getPlaceId from the response to a public variable. I get the data from the API but it looks as if the json isn't being parsed, as a result the variable is still null.

getPlaceId method using retrofit<BR>
EDITED

  1. String lat = &quot;39.748378&quot;, lng = &quot;-91.857558&quot;, placeId;
  2. Map&lt;String, String&gt; query = new HashMap&lt;&gt;();
  3. query.put(&quot;latlng&quot;, lat+&quot;,&quot;+lng);
  4. query.put(&quot;key&quot;,&quot;API_KEY&quot;);
  5. public void getPlaceId(final Map&lt;String, String&gt; query) {
  6. String BASE_URL = &quot;https://maps.googleapis.com/maps/&quot;;
  7. Retrofit retrofit;
  8. HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
  9. logging.setLevel(HttpLoggingInterceptor.Level.BODY);
  10. OkHttpClient client = new OkHttpClient.Builder()
  11. .addInterceptor(logging)
  12. .build();
  13. retrofit = new Retrofit.Builder()
  14. .baseUrl(BASE_URL)
  15. .addConverterFactory(GsonConverterFactory.create())
  16. .client(client)
  17. .build();
  18. PlacesInterface service = retrofit.create(PlacesInterface.class);
  19. Call&lt;PlacesFoo&gt; call = service.loadPlace(query);
  20. call.enqueue(new Callback&lt;PlacesFoo&gt;() {
  21. @Override
  22. public void onResponse(Call&lt;PlacesFoo&gt; call, Response&lt;PlacesFoo&gt; response) {
  23. if(response.isSuccessful()) {
  24. Log.e(&quot;getPlaceId&quot;, &quot; Valid Response: &quot; + response.body());
  25. placeId = response.body().getResults().get(0).getPlaceId();
  26. } else {
  27. System.out.println(response.errorBody());
  28. }
  29. }
  30. @Override
  31. public void onFailure(Call&lt;PlacesFoo&gt; call, Throwable t) {
  32. t.printStackTrace();
  33. Log.e(&quot;getPlaceId&quot;, &quot; Error Response: &quot; + t);
  34. }
  35. });
  36. //return placeId;
  37. }

Interface for API

  1. public interface PlacesInterface {
  2. // https://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.961452&amp;key=API_KEY
  3. @GET(&quot;api/geocode/json&quot;)
  4. Call&lt;PlacesFoo&gt; loadPlace(@QueryMap Map&lt;String, String&gt; options);
  5. }

POJO for API reply

  1. public class PlacesFoo {
  2. @SerializedName(&quot;plus_code&quot;)
  3. @Expose
  4. private PlusCode plusCode;
  5. @SerializedName(&quot;results&quot;)
  6. @Expose
  7. private List&lt;Result&gt; results = null;
  8. @SerializedName(&quot;status&quot;)
  9. @Expose
  10. private String status;
  11. public PlusCode getPlusCode() {
  12. return plusCode;
  13. }
  14. public void setPlusCode(PlusCode plusCode) {
  15. this.plusCode = plusCode;
  16. }
  17. public List&lt;Result&gt; getResults() {
  18. return results;
  19. }
  20. public void setResults(List&lt;Result&gt; results) {
  21. this.results = results;
  22. }
  23. public String getStatus() {
  24. return status;
  25. }
  26. public void setStatus(String status) {
  27. this.status = status;
  28. }
  29. public class AddressComponent {
  30. @SerializedName(&quot;long_name&quot;)
  31. @Expose
  32. private String longName;
  33. @SerializedName(&quot;short_name&quot;)
  34. @Expose
  35. private String shortName;
  36. @SerializedName(&quot;types&quot;)
  37. @Expose
  38. private List&lt;String&gt; types = null;
  39. public String getLongName() {
  40. return longName;
  41. }
  42. public void setLongName(String longName) {
  43. this.longName = longName;
  44. }
  45. public String getShortName() {
  46. return shortName;
  47. }
  48. public void setShortName(String shortName) {
  49. this.shortName = shortName;
  50. }
  51. public List&lt;String&gt; getTypes() {
  52. return types;
  53. }
  54. public void setTypes(List&lt;String&gt; types) {
  55. this.types = types;
  56. }
  57. }
  58. public class Bounds {
  59. @SerializedName(&quot;northeast&quot;)
  60. @Expose
  61. private Northeast_ northeast;
  62. @SerializedName(&quot;southwest&quot;)
  63. @Expose
  64. private Southwest_ southwest;
  65. public Northeast_ getNortheast() {
  66. return northeast;
  67. }
  68. public void setNortheast(Northeast_ northeast) {
  69. this.northeast = northeast;
  70. }
  71. public Southwest_ getSouthwest() {
  72. return southwest;
  73. }
  74. public void setSouthwest(Southwest_ southwest) {
  75. this.southwest = southwest;
  76. }
  77. }
  78. public class Geometry {
  79. @SerializedName(&quot;location&quot;)
  80. @Expose
  81. private Location location;
  82. @SerializedName(&quot;location_type&quot;)
  83. @Expose
  84. private String locationType;
  85. @SerializedName(&quot;viewport&quot;)
  86. @Expose
  87. private Viewport viewport;
  88. @SerializedName(&quot;bounds&quot;)
  89. @Expose
  90. private Bounds bounds;
  91. public Location getLocation() {
  92. return location;
  93. }
  94. public void setLocation(Location location) {
  95. this.location = location;
  96. }
  97. public String getLocationType() {
  98. return locationType;
  99. }
  100. public void setLocationType(String locationType) {
  101. this.locationType = locationType;
  102. }
  103. public Viewport getViewport() {
  104. return viewport;
  105. }
  106. public void setViewport(Viewport viewport) {
  107. this.viewport = viewport;
  108. }
  109. public Bounds getBounds() {
  110. return bounds;
  111. }
  112. public void setBounds(Bounds bounds) {
  113. this.bounds = bounds;
  114. }
  115. }
  116. public class Location {
  117. @SerializedName(&quot;lat&quot;)
  118. @Expose
  119. private Double lat;
  120. @SerializedName(&quot;lng&quot;)
  121. @Expose
  122. private Double lng;
  123. public Double getLat() {
  124. return lat;
  125. }
  126. public void setLat(Double lat) {
  127. this.lat = lat;
  128. }
  129. public Double getLng() {
  130. return lng;
  131. }
  132. public void setLng(Double lng) {
  133. this.lng = lng;
  134. }
  135. }
  136. public class Northeast {
  137. @SerializedName(&quot;lat&quot;)
  138. @Expose
  139. private Double lat;
  140. @SerializedName(&quot;lng&quot;)
  141. @Expose
  142. private Double lng;
  143. public Double getLat() {
  144. return lat;
  145. }
  146. public void setLat(Double lat) {
  147. this.lat = lat;
  148. }
  149. public Double getLng() {
  150. return lng;
  151. }
  152. public void setLng(Double lng) {
  153. this.lng = lng;
  154. }
  155. }
  156. public class Northeast_ {
  157. @SerializedName(&quot;lat&quot;)
  158. @Expose
  159. private Double lat;
  160. @SerializedName(&quot;lng&quot;)
  161. @Expose
  162. private Double lng;
  163. public Double getLat() {
  164. return lat;
  165. }
  166. public void setLat(Double lat) {
  167. this.lat = lat;
  168. }
  169. public Double getLng() {
  170. return lng;
  171. }
  172. public void setLng(Double lng) {
  173. this.lng = lng;
  174. }
  175. }
  176. public class PlusCode {
  177. @SerializedName(&quot;compound_code&quot;)
  178. @Expose
  179. private String compoundCode;
  180. @SerializedName(&quot;global_code&quot;)
  181. @Expose
  182. private String globalCode;
  183. public String getCompoundCode() {
  184. return compoundCode;
  185. }
  186. public void setCompoundCode(String compoundCode) {
  187. this.compoundCode = compoundCode;
  188. }
  189. public String getGlobalCode() {
  190. return globalCode;
  191. }
  192. public void setGlobalCode(String globalCode) {
  193. this.globalCode = globalCode;
  194. }
  195. }
  196. public class PlusCode_ {
  197. @SerializedName(&quot;compound_code&quot;)
  198. @Expose
  199. private String compoundCode;
  200. @SerializedName(&quot;global_code&quot;)
  201. @Expose
  202. private String globalCode;
  203. public String getCompoundCode() {
  204. return compoundCode;
  205. }
  206. public void setCompoundCode(String compoundCode) {
  207. this.compoundCode = compoundCode;
  208. }
  209. public String getGlobalCode() {
  210. return globalCode;
  211. }
  212. public void setGlobalCode(String globalCode) {
  213. this.globalCode = globalCode;
  214. }
  215. }
  216. public class Result {
  217. @SerializedName(&quot;address_components&quot;)
  218. @Expose
  219. private List&lt;AddressComponent&gt; addressComponents = null;
  220. @SerializedName(&quot;formatted_address&quot;)
  221. @Expose
  222. private String formattedAddress;
  223. @SerializedName(&quot;geometry&quot;)
  224. @Expose
  225. private Geometry geometry;
  226. @SerializedName(&quot;place_id&quot;)
  227. @Expose
  228. private String placeId;
  229. @SerializedName(&quot;plus_code&quot;)
  230. @Expose
  231. private PlusCode_ plusCode;
  232. @SerializedName(&quot;types&quot;)
  233. @Expose
  234. private List&lt;String&gt; types = null;
  235. public List&lt;AddressComponent&gt; getAddressComponents() {
  236. return addressComponents;
  237. }
  238. public void setAddressComponents(List&lt;AddressComponent&gt; addressComponents) {
  239. this.addressComponents = addressComponents;
  240. }
  241. public String getFormattedAddress() {
  242. return formattedAddress;
  243. }
  244. public void setFormattedAddress(String formattedAddress) {
  245. this.formattedAddress = formattedAddress;
  246. }
  247. public Geometry getGeometry() {
  248. return geometry;
  249. }
  250. public void setGeometry(Geometry geometry) {
  251. this.geometry = geometry;
  252. }
  253. public String getPlaceId() {
  254. return placeId;
  255. }
  256. public void setPlaceId(String placeId) {
  257. this.placeId = placeId;
  258. }
  259. public PlusCode_ getPlusCode() {
  260. return plusCode;
  261. }
  262. public void setPlusCode(PlusCode_ plusCode) {
  263. this.plusCode = plusCode;
  264. }
  265. public List&lt;String&gt; getTypes() {
  266. return types;
  267. }
  268. public void setTypes(List&lt;String&gt; types) {
  269. this.types = types;
  270. }
  271. }
  272. public class Southwest {
  273. @SerializedName(&quot;lat&quot;)
  274. @Expose
  275. private Double lat;
  276. @SerializedName(&quot;lng&quot;)
  277. @Expose
  278. private Double lng;
  279. public Double getLat() {
  280. return lat;
  281. }
  282. public void setLat(Double lat) {
  283. this.lat = lat;
  284. }
  285. public Double getLng() {
  286. return lng;
  287. }
  288. public void setLng(Double lng) {
  289. this.lng = lng;
  290. }
  291. }
  292. public class Southwest_ {
  293. @SerializedName(&quot;lat&quot;)
  294. @Expose
  295. private Double lat;
  296. @SerializedName(&quot;lng&quot;)
  297. @Expose
  298. private Double lng;
  299. public Double getLat() {
  300. return lat;
  301. }
  302. public void setLat(Double lat) {
  303. this.lat = lat;
  304. }
  305. public Double getLng() {
  306. return lng;
  307. }
  308. public void setLng(Double lng) {
  309. this.lng = lng;
  310. }
  311. }
  312. public class Viewport {
  313. @SerializedName(&quot;northeast&quot;)
  314. @Expose
  315. private Northeast northeast;
  316. @SerializedName(&quot;southwest&quot;)
  317. @Expose
  318. private Southwest southwest;
  319. public Northeast getNortheast() {
  320. return northeast;
  321. }
  322. public void setNortheast(Northeast northeast) {
  323. this.northeast = northeast;
  324. }
  325. public Southwest getSouthwest() {
  326. return southwest;
  327. }
  328. public void setSouthwest(Southwest southwest) {
  329. this.southwest = southwest;
  330. }
  331. }
  332. }

答案1

得分: 2

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

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

  1. public interface MyCallback {
  2. void onSuccess(String placeId);
  3. void onError(String error);
  4. }

然后你的调用将会是这样的:

  1. getPlaceId(new MyCallback() {
  2. @Override
  3. public void onSuccess(String placeId) {
  4. // 在这里你会得到地点的 ID,你可以根据 ID 进行操作
  5. Log.e("PlaceID", placeId);
  6. }
  7. @Override
  8. public void onError(String error) {
  9. // 在发生错误的情况下
  10. }
  11. });

Retrofit 调用

  1. private void getPlaceId(MyCallback myCallback) {
  2. // ...
  3. // ...
  4. PlacesInterface service = retrofit.create(PlacesInterface.class);
  5. Call<PlacesFoo> call = service.loadPlace(query);
  6. call.enqueue(new Callback<PlacesFoo>() {
  7. @Override
  8. public void onResponse(@NotNull Call<PlacesFoo> call, @NotNull Response<PlacesFoo> response) {
  9. if (response.isSuccessful()) {
  10. String placeId = response.body().getResults().get(0).getPlaceId();
  11. myCallback.onSuccess(placeId);
  12. } else {
  13. if (response.errorBody() != null) {
  14. myCallback.onError(response.errorBody().toString());
  15. }
  16. }
  17. }
  18. @Override
  19. public void onFailure(@NotNull Call<PlacesFoo> call, @NotNull Throwable t) {
  20. t.printStackTrace();
  21. myCallback.onError(t.getLocalizedMessage());
  22. }
  23. });
  24. }

要了解异步同步请求之间的区别,请查看此链接

英文:

>Retrofit supports synchronous and asynchronous request execution. Users define the concrete execution by setting a return type (synchronous) or not (asynchronous) to service methods.

Edit
You need to pass the result from the Asynchronous call through interface

  1. public interface MyCallback {
  2. void onSuccess(String placeId);
  3. void onError(String error);
  4. }

and your call will be like

  1. getPlaceId(new MyCallback() {
  2. @Override
  3. public void onSuccess(String placeId) {
  4. // here you get place Id you can do your work with id
  5. Log.e(&quot;PlaceID&quot;,placeId);
  6. }
  7. @Override
  8. public void onError(String error) {
  9. // in case of error occurred
  10. }
  11. });

Retrofit call

  1. private void getPlaceId(MyCallback myCallback) {
  2. .....
  3. .....
  4. PlacesInterface service = retrofit.create(PlacesInterface .class);
  5. Call&lt;PlacesFoo&gt; call = service.loadPlace(query);
  6. call.enqueue(new Callback&lt;PlacesFoo&gt;() {
  7. @Override
  8. public void onResponse(@NotNull Call&lt;PlacesFoo&gt; call, @NotNull Response&lt;PlacesFoo&gt; response) {
  9. if (response.isSuccessful()) {
  10. String placeId = response.body().getResults().get(0).getPlaceId();
  11. myCallback.onSuccess(placeId);
  12. } else {
  13. if (response.errorBody() != null) {
  14. myCallback.onError(response.errorBody().toString());
  15. }
  16. }
  17. }
  18. @Override
  19. public void onFailure(@NotNull Call&lt;PlacesFoo&gt; call, @NotNull Throwable t) {
  20. t.printStackTrace();
  21. myCallback.onError(t.getLocalizedMessage());
  22. }
  23. });
  24. }

to know the difference between Asynchronous and Synchronous request check this

答案2

得分: 0

首先创建一个如下的接口:

  1. public interface OnPlaceIdFoundListener {
  2. void onPlaceIdFound(String placeId);
  3. }

其次,你需要修改getPlaceId方法的签名和代码块,如下所示(看见"@@here@@!!!!!"标记处):

  1. public void getPlaceId(final Map<String, String> query, OnPlaceIdFoundListener callback) {
  2. String BASE_URL = "https://maps.googleapis.com/maps/";
  3. Retrofit retrofit;
  4. HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
  5. logging.setLevel(HttpLoggingInterceptor.Level.BODY);
  6. OkHttpClient client = new OkHttpClient.Builder()
  7. .addInterceptor(logging)
  8. .build();
  9. retrofit = new Retrofit.Builder()
  10. .baseUrl(BASE_URL)
  11. .addConverterFactory(GsonConverterFactory.create())
  12. .client(client)
  13. .build();
  14. PlacesInterface service = retrofit.create(PlacesInterface.class);
  15. Call<PlacesFoo> call = service.loadPlace(query);
  16. call.enqueue(new Callback<PlacesFoo>() {
  17. @Override
  18. public void onResponse(Call<PlacesFoo> call, Response<PlacesFoo> response) {
  19. if(response.isSuccessful()) {
  20. Log.e("getPlaceId", " Valid Response: " + response.body());
  21. String placeId = response.body().getResults().get(0).getPlaceId();
  22. callback.onPlaceIdFound(placeId); // @@here@@!!!!!
  23. } else {
  24. System.out.println(response.errorBody());
  25. callback.onPlaceIdFound(""); // @@here@@!!!!!
  26. }
  27. }
  28. @Override
  29. public void onFailure(Call<PlacesFoo> call, Throwable t) {
  30. t.printStackTrace();
  31. callback.onPlaceIdFound(""); // @@here@@!!!!!
  32. Log.e("getPlaceId", " Error Response: " + t);
  33. }
  34. });
  35. //return placeId;
  36. }

然后使用你的方法:

  1. getPlaceId(query, new OnPlaceIdFoundListener() {
  2. @Override
  3. public void onPlaceIdFound(String placeId) {
  4. Log.d("TAG", "place id is found = " + placeId);
  5. }
  6. });
英文:

first create an interface like below:

  1. public interface OnPlaceIdFoundListener {
  2. void onPlaceIdFound(String placeId);
  3. }

second you should change signature and body of getPlaceId method like below (see "@@here@@!!!!!" sign):

  1. public void getPlaceId(final Map&lt;String, String&gt; query, OnPlaceIdFoundListener callback) {
  2. String BASE_URL = &quot;https://maps.googleapis.com/maps/&quot;;
  3. Retrofit retrofit;
  4. HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
  5. logging.setLevel(HttpLoggingInterceptor.Level.BODY);
  6. OkHttpClient client = new OkHttpClient.Builder()
  7. .addInterceptor(logging)
  8. .build();
  9. retrofit = new Retrofit.Builder()
  10. .baseUrl(BASE_URL)
  11. .addConverterFactory(GsonConverterFactory.create())
  12. .client(client)
  13. .build();
  14. PlacesInterface service = retrofit.create(PlacesInterface.class);
  15. Call&lt;PlacesFoo&gt; call = service.loadPlace(query);
  16. call.enqueue(new Callback&lt;PlacesFoo&gt;() {
  17. @Override
  18. public void onResponse(Call&lt;PlacesFoo&gt; call, Response&lt;PlacesFoo&gt; response) {
  19. if(response.isSuccessful()) {
  20. Log.e(&quot;getPlaceId&quot;, &quot; Valid Response: &quot; + response.body());
  21. String placeId = response.body().getResults().get(0).getPlaceId();
  22. callback.onPlaceIdFound(placeId); // @@here@@!!!!!
  23. } else {
  24. System.out.println(response.errorBody());
  25. callback.onPlaceIdFound(&quot;&quot;); // @@here@@!!!!!
  26. }
  27. }
  28. @Override
  29. public void onFailure(Call&lt;PlacesFoo&gt; call, Throwable t) {
  30. t.printStackTrace();
  31. callback.onPlaceIdFound(&quot;&quot;); // @@here@@!!!!!
  32. Log.e(&quot;getPlaceId&quot;, &quot; Error Response: &quot; + t);
  33. }
  34. });
  35. //return placeId;
  36. }

then use your method.

  1. getPlaceId(query, new OnPlaceIdFoundListener() {
  2. @Override
  3. public void onPlaceIdFound(String placeId) {
  4. Log.d(&quot;TAG&quot;, &quot;place id is found = &quot;+ placeId);
  5. }
  6. });

huangapple
  • 本文由 发表于 2020年8月17日 03:06:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/63440933.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定