等待 Retrofit 2 异步调用的响应
Wait for response from Retrofit 2 asynchronous call
在我的 Android 中 activity 我有一个异步调用 google 映射 API 在一个方法中看到下面的代码:
public void reverseGeocode(String lat, String lng) {
String geocodeApiUrl = getUrl(lat, lng);
GoogleService googleService = GoogleServiceBuilder.buildService(GoogleService.class);
Call<Address> geocodeRequest = googleService.geocodeAddress(geocodeApiUrl);
geocodeRequest.enqueue(new Callback<Address>() {
@Override
public void onResponse(Call<Address> call, Response<Address> response) {
if (response.errorBody() == null) {
if (response.body().getResults().length > 0) {
if (response.body().getResults()[0].getFormatted_address() != null) {
dropOffAddress = response.body().getResults()[0].getFormatted_address();
}
}
} else {
Toast.makeText(AdressPicker.this, "An error has occured", Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<Address> call, Throwable t) {
Toast.makeText(AdressPicker.this, "An error has occured", Toast.LENGTH_LONG).show();
}
});
}
此方法在 Google 地图标记的 onMarkerDragEnd 回调函数中调用,请参见下面的代码:
@Override
public void onMarkerDragEnd(Marker marker) {
double lat = marker.getPosition().latitude;
double lng = marker.getPosition().longitude;
reverseGeocode(String.valueOf(lat), String.valueOf(lng));
marker.setSnippet(dropOffAddress);
marker.showInfoWindow();
editor.putString("dropOffAddress", dropOffAddress);
editor.putString("lat", String.valueOf(lat));
editor.putString("lng", String.valueOf(lng));
editor.apply();
}
这里的问题是我第一次移动标记时调用了 reverseGeocode 方法但没有等待 onMarkerDragEnd继续执行并将 null 放入 dropOffAddress 变量的值中,该变量旨在显示在标记的片段中。
我的问题是如何在继续执行之前等待 reverseGeocode 方法在 onMarkerDragEnd 中的响应?
谢谢。
您可以使用 java.utils.Concurrent class 中的 CountDownLatch
。
这是一个例子:
public class DoSomething {
private Address dropoffAddr;
private CountDownLatch dropoffAddrLatch = new CountDownLatch(1);
public void getAddressCallback(Address addr) {
dropoffAddr = addr;
dropoffAddrLatch.countDown();
}
@Override
public void onMarkerDragEnd(Marker marker) {
//your stuff
reverseGeocode(...); //you should call getAddressCallback once you have everything
dropOffAddrLatch.await(); //this will wait until getAddressCallBack has returned,
// you can call dropoffAddrLatch.countDown() wherever you want.
//finish your stuff
}
}
唯一的就是你。需要的是标记,只需将其作为参数传递给你的改造 api 调用类似这样的东西。
public void reverseGeocode(String lat, String lng, Marker marker) {
String geocodeApiUrl = getUrl(lat, lng);
GoogleService googleService = GoogleServiceBuilder.buildService(GoogleService.class);
Call<Address> geocodeRequest = googleService.geocodeAddress(geocodeApiUrl);
geocodeRequest.enqueue(new Callback<Address>() {
@Override
public void onResponse(Call<Address> call, Response<Address> response) {
if (response.errorBody() == null) {
if (response.body().getResults().length > 0) {
if (response.body().getResults()[0].getFormatted_address() != null) {
dropOffAddress = response.body().getResults()[0].getFormatted_address();
applyGeoCode(marker)
}
}
} else {
Toast.makeText(AdressPicker.this, "An error has occured", Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<Address> call, Throwable t) {
Toast.makeText(AdressPicker.this, "An error has occured", Toast.LENGTH_LONG).show();
}
});
}
现在从这里调用传递标记的方法
public void applyGeoCode(Marker marker){
double lat = marker.getPosition().latitude;
double lng = marker.getPosition().longitude;
marker.setSnippet(dropOffAddress);
marker.showInfoWindow();
editor.putString("dropOffAddress", dropOffAddress);
editor.putString("lat", String.valueOf(lat));
editor.putString("lng", String.valueOf(lng));
editor.apply();
}
然后这样调用
@Override
public void onMarkerDragEnd(Marker marker) {
reverseGeocode(String.valueOf(lat), String.valueOf(lng), marker);
}
在我的 Android 中 activity 我有一个异步调用 google 映射 API 在一个方法中看到下面的代码:
public void reverseGeocode(String lat, String lng) {
String geocodeApiUrl = getUrl(lat, lng);
GoogleService googleService = GoogleServiceBuilder.buildService(GoogleService.class);
Call<Address> geocodeRequest = googleService.geocodeAddress(geocodeApiUrl);
geocodeRequest.enqueue(new Callback<Address>() {
@Override
public void onResponse(Call<Address> call, Response<Address> response) {
if (response.errorBody() == null) {
if (response.body().getResults().length > 0) {
if (response.body().getResults()[0].getFormatted_address() != null) {
dropOffAddress = response.body().getResults()[0].getFormatted_address();
}
}
} else {
Toast.makeText(AdressPicker.this, "An error has occured", Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<Address> call, Throwable t) {
Toast.makeText(AdressPicker.this, "An error has occured", Toast.LENGTH_LONG).show();
}
});
}
此方法在 Google 地图标记的 onMarkerDragEnd 回调函数中调用,请参见下面的代码:
@Override
public void onMarkerDragEnd(Marker marker) {
double lat = marker.getPosition().latitude;
double lng = marker.getPosition().longitude;
reverseGeocode(String.valueOf(lat), String.valueOf(lng));
marker.setSnippet(dropOffAddress);
marker.showInfoWindow();
editor.putString("dropOffAddress", dropOffAddress);
editor.putString("lat", String.valueOf(lat));
editor.putString("lng", String.valueOf(lng));
editor.apply();
}
这里的问题是我第一次移动标记时调用了 reverseGeocode 方法但没有等待 onMarkerDragEnd继续执行并将 null 放入 dropOffAddress 变量的值中,该变量旨在显示在标记的片段中。
我的问题是如何在继续执行之前等待 reverseGeocode 方法在 onMarkerDragEnd 中的响应?
谢谢。
您可以使用 java.utils.Concurrent class 中的 CountDownLatch
。
这是一个例子:
public class DoSomething {
private Address dropoffAddr;
private CountDownLatch dropoffAddrLatch = new CountDownLatch(1);
public void getAddressCallback(Address addr) {
dropoffAddr = addr;
dropoffAddrLatch.countDown();
}
@Override
public void onMarkerDragEnd(Marker marker) {
//your stuff
reverseGeocode(...); //you should call getAddressCallback once you have everything
dropOffAddrLatch.await(); //this will wait until getAddressCallBack has returned,
// you can call dropoffAddrLatch.countDown() wherever you want.
//finish your stuff
}
}
唯一的就是你。需要的是标记,只需将其作为参数传递给你的改造 api 调用类似这样的东西。
public void reverseGeocode(String lat, String lng, Marker marker) {
String geocodeApiUrl = getUrl(lat, lng);
GoogleService googleService = GoogleServiceBuilder.buildService(GoogleService.class);
Call<Address> geocodeRequest = googleService.geocodeAddress(geocodeApiUrl);
geocodeRequest.enqueue(new Callback<Address>() {
@Override
public void onResponse(Call<Address> call, Response<Address> response) {
if (response.errorBody() == null) {
if (response.body().getResults().length > 0) {
if (response.body().getResults()[0].getFormatted_address() != null) {
dropOffAddress = response.body().getResults()[0].getFormatted_address();
applyGeoCode(marker)
}
}
} else {
Toast.makeText(AdressPicker.this, "An error has occured", Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call<Address> call, Throwable t) {
Toast.makeText(AdressPicker.this, "An error has occured", Toast.LENGTH_LONG).show();
}
});
}
现在从这里调用传递标记的方法
public void applyGeoCode(Marker marker){
double lat = marker.getPosition().latitude;
double lng = marker.getPosition().longitude;
marker.setSnippet(dropOffAddress);
marker.showInfoWindow();
editor.putString("dropOffAddress", dropOffAddress);
editor.putString("lat", String.valueOf(lat));
editor.putString("lng", String.valueOf(lng));
editor.apply();
}
然后这样调用
@Override
public void onMarkerDragEnd(Marker marker) {
reverseGeocode(String.valueOf(lat), String.valueOf(lng), marker);
}