Observable throwing Exception When Updating MutableLiveData

Viewed 125

I am having issues when trying to update my MutableLiveData. I am calling a login function from my ViewModel to update my UI. In my ViewModel, I make a call to my API server, but when I call .notify(), I get a crash:

java.lang.IllegalMonitorStateException: object not locked by thread before notify()

Where should I put this so it works

Here is my XML file

    <data>
        <variable
            name="viewModel"
            type="com.kidzmedia.radio.activities.login.LoginViewModel" />
    </data>

....

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="96dp"
        android:onClick="@{() -> viewModel.doLogin()}"
        android:text="Login" />

My ViewModel

public class LoginViewModel extends ViewModel {
    private MutableLiveData<User> userMutableLiveData;

....

    public void doLogin() {
        userMutableLiveData = userApi.loginUser(email, password);
        Log.i("LOGIN", "do Login");

        //userMutableLiveData.setValue(tmpUser.getValue());
    }

    LiveData<User> getUser() {
        if (userMutableLiveData == null) {
            userMutableLiveData = new MutableLiveData<>();
        }

        return userMutableLiveData;
    }

my UI

public class LoginActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ActivityLoginBinding activityLoginBinding = DataBindingUtil.setContentView(this, R.layout.activity_login);
        //activityLoginBinding.setViewModel(ViewModelProviders.of(this).get(LoginViewModel.class);

        LoginViewModel loginViewModel = ViewModelProviders.of(this).get(LoginViewModel.class);
        activityLoginBinding.setViewModel(loginViewModel);

        loginViewModel.getUser().observe(this, new Observer<User>() {

            @Override
            public void onChanged(User user) {
                if (user != null)
                    // DO STUFF
            }
        });
    }
}

My Api Server:

public class UserApi {

    private final String TAG = getClass().getSimpleName();

    public MutableLiveData<User> loginUser(String email, String password) {


        User loginUser = new User(email, password);

        final MutableLiveData<User> mutableLiveData = new MutableLiveData<>();

        UserService userApi = APIUtils.getUserService();
        userApi.doLoginUser(loginUser).enqueue(new Callback<User>() {
            @Override
            public void onResponse(Call<User> call, Response<User> response) {
                mutableLiveData.setValue(response.body());

                // THIS IS WHERE IT CRASHES
                mutableLiveData.notify();
            }
        });

        return mutableLiveData;
    }
1 Answers

Answer for your comment

if I remove the ".notify()", then how can I get the MutableLiveData to update?

I know only 2 ways. May be it help you.

  1. You can send callback function to loginUser() in arguments.

  2. You can use execute instead enqueue and work with request synchronously. But you'll need to do this in another thread.

Related