【问题标题】:Return data from retrofit onResponse从改造 onResponse 返回数据
【发布时间】:2020-01-31 13:08:28
【问题描述】:

我正在做一个基本的 android 应用程序,它执行一个简单的登录againts API。我需要返回接收到的数据,但改造 onResponse 方法的返回类型为 void。我的代码是:

package com.example.deberesloginjava.data;

import android.util.Log;

import com.example.deberesloginjava.data.APIServices.Post;
import com.example.deberesloginjava.data.model.LoggedInUser;

import java.io.IOException;

import com.example.deberesloginjava.data.APIServices.APIService;
import com.example.deberesloginjava.data.APIServices.ApiUtils;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

import static android.content.ContentValues.TAG;

/**
 * Class that handles authentication w/ login credentials and retrieves user information.
 */

public class LoginDataSource {

    private APIService mAPIService;

    public void getData(Callback<Result<LoggedInUser>> callback){
        apiClient.getData().enqueue(callback);
    }

    public Result<LoggedInUser> login(String username, String password) {

        try {

            mAPIService = ApiUtils.getAPIService();

           mAPIService.login(username, password, "password").enqueue(new Callback<Post>() {
                @Override
                public void onResponse(Call<Post> call, Response<Post> response) {
                    if(response.isSuccessful()) {
                        LoggedInUser loggedInUser;
                        loggedInUser = new LoggedInUser(response.body().getUserName(),response.body().getUserName(), response.body().getAccess_token());
                        return new Result.Success<>(loggedInUser);
                    }
                }



                @Override
                public void onFailure(Call<Post> call, Throwable t) {
                    Log.e(TAG, "Unable to submit post to API.");
                }
            });

        } catch (Exception e) {
            return new Result.Error(new IOException("Error logging in", e));
        }
    }
}

我发现至少有两个这样的问题,并且都有几乎相同的回调解决方案,但我无法在我的情况下复制它。

提前致谢。

【问题讨论】:

  • 你想实际返回什么?否则,您是否希望通过 Toast 成功登录尝试导航到另一个视图?
  • 推荐使用改造的方法是将您的响应建模到数据类中
  • 在 java 中无法以异步方式执行此操作。如果你想要一个除 void 以外的返回类型而不阻塞 ui 线程,你应该看看 kotlin 挂起函数。
  • @Blu 我想返回一个带有经过身份验证的用户数据的 Result 以用 Toast 显示它。我使用的基础是默认的 Android Studio 登录模板。
  • @titanlux619 检查我的答案

标签: android retrofit retrofit2


【解决方案1】:

您必须添加自定义回调来处理这种情况。你不能在 onResponse() 和 onFailure() 中返回任何东西

public interface CustomCallback {

    void onSucess(Result<LoggedInUser> value);
    void onFailure();
}

像这样更新你的方法:

public void login(String username, String password,CustomCallback customCallback) {

        try {

            mAPIService = ApiUtils.getAPIService();

           mAPIService.login(username, password, "password").enqueue(new Callback<Post>() {
                @Override
                public void onResponse(Call<Post> call, Response<Post> response) {
                    if(response.isSuccessful()) {
                        LoggedInUser loggedInUser;
                        loggedInUser = new LoggedInUser(response.body().getUserName(),response.body().getUserName(), response.body().getAccess_token());
                        customCallback.onSucess(new Result.Success<>(loggedInUser));
                    }
                }


                @Override
                public void onFailure(Call<Post> call, Throwable t) {
                    Log.e(TAG, "Unable to submit post to API.");
                    customCallback.onFailure();
                }
            });

        } catch (Exception e) {
            e.printStactTrace();
        }
    }

你必须像下面这样调用你的 api:

login("user name","passwor",new CustomCallback(){
       @Override
       public void onSucess(Result<LoggedInUser> value){
      //do your success code here
     }
       @Override
       public void onFailure(){
      }

});

【讨论】:

  • 我使用此代码作为基础,并通过与我的特定案例相关的一些更改,它最终可以工作。非常感谢!
【解决方案2】:

实际上你不能返回一个值,而是你可以尝试在 DTO 中创建一个传递/存储数据的方法并在你的respose.IsSuccessful 中调用该方法。将响应 json 的对象传递给用于存储所需内容的方法,例如令牌、用户名 n 等。

你可以试试看

               if(response.isSuccessful()) {
                    // just a loader untill all operations are done
                    progressBar.SetVisibility(View.Visible);
                    //Make a toast here for successful login
                    LoggedInUser loggedInUser;
                    loggedInUser = new LoggedInUser(response.body().getUserName(),response.body().getUserName(), response.body().getAccess_token());
                    UserDTO(loggedInUser);//it will save the users login details.
                }
                else{
                    //Make a toast as per your responce error.code as Invalid Password or any other error
                }

在 UserDTO() 中,您可以为用户创建一个登录会话,以便用户下次使用该应用程序时自动登录,他不需要再次输入 ID 和密码。 在所有处理之后导航到你想要的视图StartActivity()

希望这是您想要实现的目标。

【讨论】:

    猜你喜欢
    • 2020-02-10
    • 2020-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-26
    • 2020-03-06
    • 1970-01-01
    • 2017-04-07
    相关资源
    最近更新 更多