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