2

I use retrofit to get the response correctly, then I pass the response to an object in the response body, while it fails to get the object in UI thread, there is a NullPointerException Error, I think it's the problem of the asynchronous request, how can I avoid this problem?

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button = findViewById(R.id.button);

    util = new Util(this);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            util.login("sdjfl@gmail.com", "sdjflsdkf");

            // There is a NullPointerException? How Can I
            // use this methond correctly in this way?
            Log.d("user", util.getUserInfo().toString());
        }
    });
}

public class Util {
    private UserInfo userInfo;

    public UserInfo getUserInfo() {
        return userInfo;
    }

    public void login(final String email, final String password) {
        Call<UserInfo> loginCall = apiInterface.login(email, password);
        loginCall.enqueue(new Callback<UserInfo>() {
            @Override
            public void onResponse(Call<UserInfo> call, Response<UserInfo> response) {
                userInfo = response.body();
        }

        @Override
        public void onFailure(Call<UserInfo> call, Throwable t) {
        }
    });
}

1 Answers1

0

Move this line inside the onResponse()

Log.d("user", util.getUserInfo().toString());

You are getting the user info object too realy, it's null at the point you are trying to access it

Like that

public class Util {
    public interface Callback {
        void onResponse(UserInfo info);
    }
    private UserInfo userInfo;

    public UserInfo getUserInfo() {
        return userInfo;
    }

    public void login(final String email, final String password, final Callback callback) {
        Call<UserInfo> loginCall = apiInterface.login(email, password);
        loginCall.enqueue(new Callback<UserInfo>() {
            @Override
            public void onResponse(Call<UserInfo> call, Response<UserInfo> response) {
                userInfo = response.body();
                callback.onResponse(userInfo);
                Log.d("user", userInfo.toString());
        }

        @Override
        public void onFailure(Call<UserInfo> call, Throwable t) {
        }
    });
}

And here's how you use it

Util.login("email", "password", new Util.Callback() {
   void onResponse(User info) {
       // Update UI
   }
});

Please be aware that this callback can leak memory, make sure to clean it if you leave your current activity/fragment.

elmorabea
  • 3,243
  • 1
  • 14
  • 20