【问题标题】:How can I use the Retrofit response outside the OnResponse function so I can return it up the recommended architecture model?如何在 OnResponse 函数之外使用 Retrofit 响应,以便将其返回到推荐的架构模型?
【发布时间】: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,所以我不确定如何回答我自己的问题。

标签: java android callback


【解决方案1】:

我一路切换到Kotlin,所以这可能不是正确的Java,但它显示了过程

  1. 设置用户模型为LiveData
  2. 使用.postValue()更新用户模型
  3. 在视图模型中为用户模型设置observer(未显示)
public class LoginDataSource {
    public static Retrofit retrofit = null;
    MutableLiveData<LoggedInUser> user=new MutableLiveData<>(); // changed this to LiveData so it can be observed from the viewmodel

    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);
            loggedInUser = endPoint.getUser("login", username, password);
            user.postValue(loggedInUser); // updated the livedata here
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-29
    • 2018-09-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多