我遇到了一种奇怪的行为。我的应用程序有一个主要活动,包括导航器布局和默认列表片段。列表片段使用Retrofit客户端来获取内容。选择列表项时会显示详细信息视图。在小屏幕上,详细视图通过单独的活动加载。该活动还使用Retrofit客户端来获取详细信息。然后,可以从导出新活动的导航器中选择一个选项。该活动也使用Retrofit客户端发送数据。
列表和详细信息活动可以很好地调用Retrofit方法。我可以看到日志和事情按预期工作。但是,通过导航选项打开的第三个活动会尝试调用Retrofit忽略的Retrofit客户端方法。
在所有情况下,Retrofit客户端都以相同的方式实例化:
protected ServerApi buildApi(String serverEndpoint) {
Gson gson = new GsonBuilder()
.create();
RestAdapter restAdapter = new RestAdapter.Builder()
.setLog(new AndroidLog("ServerApi"))
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(serverEndpoint)
.setErrorHandler(new ApiErrorHandler())
.setConverter(new GsonConverter(gson))
.build();
return restAdapter.create(ServerApi.class);
}
在列表和详细信息活动中,我可以看到详细的Retrofit日志条目。但是,当我在第三个活动中调用类似构造的Retrofit客户端时,没有日志消失,不会抛出任何错误,logcat不会打印任何内容。它几乎就像调用被忽略了一样。
我确信服务器端点已正确设置,并且我还确保执行调用。起初,我认为这可能是由于客户端在onCreate
中发生并在单独的线程上执行。但是,在客户端创建之后立即进行测试调用并不会产生任何结果。
有人知道在一项活动中可能导致这种奇怪行为的原因而不是其他活动吗?
更新1
是的,我尝试过无处不在的日志。我更加绝望的Retrofit客户端构建看起来像这样:
protected class ApiErrorHandler implements ErrorHandler {
@Override
public Throwable handleError(RetrofitError cause) {
Log.e(TAG, "Got API error " + cause);
Response r = cause.getResponse();
Throwable throwable = null;
if (r == null) {
return cause;
}
// Try to interpret the response
String responseBody = new String(((TypedByteArray) r.getBody()).getBytes());
Gson gson = new GsonBuilder().create();
BaseResponse response = null;
try {
response = gson.fromJson(responseBody, BaseResponse.class);
}
catch (Exception e) {
Log.e(TAG, "Could not parse the error response:" + e.getMessage());
}
return new ServerApiException(response.getErrorMessage());
}
}
protected class ApiRequestInterceptor implements RequestInterceptor {
@Override
public void intercept(RequestFacade request) {
Log.d(TAG, "Intercepted API request: " + request.toString());
}
}
RestAdapter restAdapter = new RestAdapter.Builder()
.setLog(new AndroidLog("ServerApi"))
.setLogLevel(RestAdapter.LogLevel.FULL)
.setEndpoint(mServerUrl)
.setErrorHandler(new ApiErrorHandler())
.setConverter(new GsonConverter(gson))
.setRequestInterceptor(new ApiRequestInterceptor())
.setProfiler(new Profiler() {
@Override
public Object beforeCall() {
Log.d("RetrofitProfiler", "Before call to retrofit");
return null;
}
@Override
public void afterCall(Profiler.RequestInformation requestInfo, long elapsedTime, int statusCode, Object beforeCallData) {
Log.d("RetrofitProfiler", String.format("HTTP %d %s %s (%dms)",
statusCode, requestInfo.getMethod(), requestInfo.getRelativePath(), elapsedTime));
}
})
.build();
更新2
好的,我错了,但不知道Retrofit至少依赖一个订户出席。我想这是有道理的,现在我想起来了......但它并非一劳永逸。
我做错了什么:
mClient = new ServerClient(mServerEndpoint, mAccountToken);
mUvClient.getFeed(mFeedId);
这是我不知道的部分。您需要订阅observable才能执行:
mClient = new ServerClient(mServerEndpoint, mAccountToken);
mUvClient.getFeed(mFeedId)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<FeedInfo>() {
@Override
public void onNext(FeedInfo feedInfo) {
Log.d(TAG, "on Next");
}
@Override
public void onCompleted() {
Log.d(TAG, "on completed");
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "on error");
}
});
这会生成预期的Retrofit详细日志和结果。无论如何,我希望这有助于某人。
答案 0 :(得分:0)
问题是我没有订阅Retrofit API生成的Observable。我认为无论如何它都会发射,但它没有并且需要订阅。希望这有助于其他可能遇到此问题的人。