【发布时间】:2021-05-20 16:11:50
【问题描述】:
这个问题来自How can I use the Retrofit response outside the OnResponse function?,但我不能发表评论,所以我在这里问自己。
我正在尝试使用 Android Studio 登录模板,因为它遵循推荐的架构,但我无法在 LoginDataSource.login 中返回结果。结果被困在 Call.enqueue 函数中,我无法将其取出返回。我已经复制了上面链接中建议的回调,但这只是将结果捕获在一个新类中。
如何访问我的服务器返回的 LoggedInUser 以返回到我的存储库?
原始尝试:用户卡在 Call.enqueue - onResponse
public class LoginDataSource {
public static Retrofit retrofit = null;
LoggedInUser user;
public Result<LoggedInUser> login(String username, String password) {
user = new LoggedInUser();
try {
// TODO: handle loggedInUser authentication
retrofit = new Retrofit.Builder()
.baseUrl("https://myserver")
.addConverterFactory(GsonConverterFactory.create())
.build();
PostEndPoint endPoint = retrofit.create(PostEndPoint.class);
Call<LoggedInUser> call = endPoint.getUser("login", username, password);
call.enqueue(new Callback<LoggedInUser>() {
@Override
public void onResponse(Call<LoggedInUser> call, Response<LoggedInUser> response) {
Log.d(TAG, "onResponse: code " + response.code());
if (response.isSuccessful()){
callback.getUser();
user = response.body();
Log.d(TAG, "onResponse: " + user); // this returns valid user data
}
}
});
Log.d(TAG, "retrofit complete:" + user.getName()); // this returns null
return new Result.Success<>(user);
}
}
}
实现回调后:用户卡在 GetUserResponse - getUser
public class LoginDataSource {
public static Retrofit retrofit = null;
LoggedInUser user;
public Result<LoggedInUser> login(String username, String password) {
user = new LoggedInUser();
try {
// TODO: handle loggedInUser authentication
retrofit = new Retrofit.Builder()
.baseUrl("https://myserver")
.addConverterFactory(GsonConverterFactory.create())
.build();
PostEndPoint endPoint = retrofit.create(PostEndPoint.class);
Call<LoggedInUser> call = endPoint.getUser("login", username, password);
sendLoginRequest(call, new GetUserResponse(){
@Override
public void getUser(LoggedInUser userFromResponse) {
user = userFromResponse;
}
});
Log.d(TAG, "retrofit complete:" + user.getName()); // this returns null
return new Result.Success<>(user);
}
}
private void sendLoginRequest (Call call, final GetUserResponse callback) {
call.enqueue(new Callback<LoggedInUser>() {
@Override
public void onResponse(Call<LoggedInUser> call, Response<LoggedInUser> response) {
if (response.isSuccessful()){
callback.getUser(response.body());
}
}
});
}
}
public interface GetUserResponse {
void getUser(LoggedInUser user);
}
我觉得我需要让 sendLoginRequest 返回用户,但我不知道该怎么做。我是否朝着正确的方向前进?欢迎任何建议。
【问题讨论】:
-
如果你知道 LiveData 和 Hilt,你可以使用依赖注入在存储库类中获取你的改造实例。然后你可以从存储库类发送请求,然后设置你对 Livedata 的响应。如果任何活动类观察实时数据将获得实时结果。
-
你说的我不太明白,但它给了我一些阅读的东西。谢谢。
-
我花了一段时间来完成所有工作。找到完整的代码实验室会产生很大的不同。 Hilt 使依赖注入更容易,但解决方案不需要它。使 LoggedInUser 成为 LiveData 变量,使用 LoggedInUser.postValue(user) 从改造线程更新它,然后从视图模型中观察 LoggedInUser 是答案,尽管这意味着更改提供的基本代码。我也一路切换到 Kotlin,所以我不确定如何回答我自己的问题。