因此,为了遵守职责分离原则,我试图让下面的改进方法 (listNearestAirports) 将列表返回给演示者(在不同的包中)。但是我注意到改造很难,从必须在我的方法范围之外声明列表开始,到我只能在 onResponse 方法中遍历列表的事实(当我尝试返回列表时,我得到一个空指针异常)。请参阅下面的代码:
public class NearestAirports {
List<GeoSearchResult> airportsList;
public List<GeoSearchResult> listNearestAirports(String lat, String lng) {
String reuquestBody = "{Escaped_JSON_request}";
AirportApi.Factory.getInstance().getAirports(requestBody).enqueue(new Callback<AirportCodes>() {
public void onResponse(Call<AirportCodes> call, Response<AirportCodes> response) {
airportsList = response.body().getGeoSearchRS().getGeoSearchResults().getGeoSearchResult();
//Here the list is populated successfully every time and I can iterate through it
System.out.println(airportsList.iterator().next().getCity());
}
public void onFailure(Call<AirportCodes> call, Throwable t) {
System.out.println("failed");
if (t instanceof IOException) {
System.out.println("actual network failure");
}
else {
System.out.println("conversion issue);
}
}
});
//Should return list, but at this point the list is null
return airportsList;
}
}
我想向 main() 返回一个列表,所以我可以执行以下操作:
NearestAirports nearest = new NearestAirports();
airportsList = nearest.listNearestAirports(lat, lng);
System.out.println(airportsList.iterator().next().getCity());
for (GeoSearchResult airport : airportsList) {
System.out.print(airport.getId() + ", ");
System.out.println(airport.getName());
}
返回改造响应的最简单方法是什么? 我需要使用灭菌吗?或者将从改造中获取响应与处理和呈现响应分开的最佳方法是什么?
==========================*更新*=========== ==============
问题好像和访问内部类有关
我试图在内部类之外声明一个变量,希望我可以为该变量分配我从改造中获得的响应。
这失败了,因为:
1. 我收到一条错误消息:从内部类访问的变量必须声明为 final。
好吧
2. 我将其声明为 final,但随后收到另一条错误消息:无法分配此变量,因为它已声明为 final。
这里讨论了一个技巧,它对我的具体情况不起作用:
Local variable access to inner class needs to be declared final
我发现尝试将逻辑和 retrofit 响应与 Activity 分开很困难,因为最终我想在 Activity/fragment 中显示响应,这在很大程度上依赖于 View 对象,在 UI 线程中执行操作等。
如何在不借助 Rx java 和 Android 的 dataBinding ViewModel 等的情况下为一个简单的应用解决这个问题?
最佳答案
问题是您正在尝试使用异步代码实现同步行为。有人可能会争辩说,您最好选择一种方法并始终如一地使用它。
更具体地说,要么:
选项 1 重构您的服务 API (Retrofit) 以实现同步行为
不要使用带有回调的 Retrofit,而是同步执行网络调用,以便您可以立即处理响应:
public class AirportApi {
public Call<AirportCodes> getAirports(@Body...);
}
public class NearestAirports {
public List<GeoSearchResult> listNearestAirports(String lat, String lng) {
final Response<AirportCodes> airportCodes = AirportApi.Factory.getInstance()
.getAirports(requestBody)
.execute();
// interrogate response and transform AirportCodes into List<GeoSearchResult>
// don't forget to account for failures
}
选项 2 - 重构您的消费者代码以使用异步数据类型(即 Future
、Single
等)
(作为示例...)更改 API 以返回 RxJava Single
。然后从您需要数据的地方调用 API 并订阅调用调用的结果。
public class AirportApi {
public Single<AirportCodes> getAirports(@Body...);
}
public class AirportDisplayActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
AirportApi.Factory.getInstance()
.getAirports(requestBody)
.subscribe(
onSuccess = {...},
onError = {...}
);
}
}
关于java - 在另一个类中使用改造响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47600873/