Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/367.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 更新MutableLiveData时引发可观察异常_Java_Android_Android Livedata - Fatal编程技术网

Java 更新MutableLiveData时引发可观察异常

Java 更新MutableLiveData时引发可观察异常,java,android,android-livedata,Java,Android,Android Livedata,我在尝试更新我的MutableLiveData时遇到问题。我正在从我的ViewModel调用一个登录函数来更新我的UI。在我的ViewModel中,我调用了我的API服务器,但当我调用.notify()时,我遇到了崩溃: java.lang.IllegalMonitorStateException:对象在notify()之前未被线程锁定 我应该把它放在哪里才能工作 这是我的XML文件 <data> <variable name=&

我在尝试更新我的MutableLiveData时遇到问题。我正在从我的ViewModel调用一个登录函数来更新我的UI。在我的ViewModel中,我调用了我的API服务器,但当我调用.notify()时,我遇到了崩溃:

java.lang.IllegalMonitorStateException:对象在notify()之前未被线程锁定

我应该把它放在哪里才能工作

这是我的XML文件

    <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" />

....
我的视图模型

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;
    }
public类LoginViewModel扩展了ViewModel{
私有MutableLiveData用户MutableLiveData;
....
公共空间多洛金(){
userMutableLiveData=userApi.loginUser(电子邮件、密码);
Log.i(“登录”、“做登录”);
//userMutableLiveData.setValue(tmpUser.getValue());
}
LiveData getUser(){
if(userMutableLiveData==null){
userMutableLiveData=新的MutableLiveData();
}
返回userMutableLiveData;
}
我的用户界面

公共类LoginActivity扩展了AppCompatActivity{
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
ActivityLoginBinding ActivityLoginBinding=DataBindingUtil.setContentView(this,R.layout.activity\u login);
//activityLoginBinding.setViewModel(ViewModelProviders.of(this.get)(LoginViewModel.class);
LoginViewModel LoginViewModel=ViewModelProviders.of(this.get)(LoginViewModel.class);
activityLoginBinding.setViewModel(loginViewModel);
loginViewModel.getUser().observe(这是一个新的观察者(){
@凌驾
更改后的公共void(用户){
如果(用户!=null)
//做事
}
});
}
}
我的Api服务器:

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;
    }
公共类UserApi{
私有最终字符串标记=getClass().getSimpleName();
公共MutableLiveData登录用户(字符串电子邮件、字符串密码){
用户登录用户=新用户(电子邮件、密码);
final MutableLiveData MutableLiveData=新的MutableLiveData();
UserService userApi=APIUtils.getUserService();
userApi.doLoginUser(loginUser).enqueue(新回调(){
@凌驾
公共void onResponse(调用、响应){
mutableLiveData.setValue(response.body());
//这就是它崩溃的地方
mutableLiveData.notify();
}
});
返回可变的livedata;
}

回答您的意见

如果删除“.notify()”,那么如何获取要更新的MutableLiveData

我只知道两种方法。也许对你有帮助

  • 您可以将回调函数发送到参数中的
    loginUser()

  • 您可以使用
    execute
    代替
    enqueue
    并同步处理请求。但您需要在另一个线程中执行此操作


  • 为什么需要调用
    notify()
    ?这是一个用于同步的非常低级的java API,考虑到LiveData的工作方式,您不应该在Android应用程序中使用它。如果您查看我在LoginViewModel中的函数“public void doLogin()”,您会看到我注释掉的一些代码,这不起作用。用户界面为空(感谢您的帮助)这并不能真正帮助我理解为什么您需要调用
    notify()
    。该方法只能在同步块中调用,您在这里没有,也没有必要调用。我建议您对该错误消息进行web搜索,以了解更多信息。如果我删除“.notify()”命令,可以,那么我如何才能让可变LiveData更新?它会自动更新-这就是LiveData的工作方式。所有观察者都会看到更新后的值。你可能想重新表述你的问题,具体是什么没有按照你期望的方式工作。太棒了,整个周末我都在绞尽脑汁,它解决了我的问题。谢谢!
    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;
        }