首页 > 解决方案 > 应该返回 LiveData 的房间查询总是返回 NULL

问题描述

我想使用 Room/SQLLite 在 android 中创建登录屏幕。启动登录活动后,将在数据库中插入一个用户对象。

当按下登录按钮时,我想通过我填写的用户名查找用户。然后我会检查我提供的密码是否是正确的密码。基于此,我将进行另一项活动,否则我将显示一条错误消息。

但这会出错,下一个代码总是返回 NULL,所以我总是会显示错误消息。

UserWithWorkorders userWithWorkorders = ie4ViewModel.getUserWithWorkorders(username.getText().toString()).getValue();

这是 UserDao 中的查询。如您所见,它返回 LiveDate。

 @Query("SELECT * FROM User WHERE username =:username")
 LiveData<UserWithWorkorders> getUserWithWorkorders(String username);

这是我的登录活动的 onCreate():

@Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        IE4ViewModel ie4ViewModel = new ViewModelProvider(this).get(IE4ViewModel.class);

        User user = new User("John", "Doe", "john", "doe");
        ie4ViewModel.insertUser(user);

        final Button loginButton = findViewById(R.id.loginButton);
        final EditText username = findViewById(R.id.username);
        final EditText password = findViewById(R.id.password);
        final TextView errorMessage = findViewById(R.id.errorMessage);


        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                UserWithWorkorders userWithWorkorders = ie4ViewModel.getUserWithWorkorders(username.getText().toString()).getValue();

                if (userWithWorkorders != null) {
                    if(userWithWorkorders.user.getPassword().equals(password.getText().toString())){
                        Intent i = new Intent(LoginActivity.this, WorkordersActivity.class);
                        i.putExtra("userObject", userWithWorkorders);
                        startActivity(i);
                    }
                    else {
                        errorMessage.setVisibility(View.VISIBLE);
                    }
                }
                else {
                    errorMessage.setVisibility(View.VISIBLE);
                }

            }
        });

        ie4ViewModel.getUsersWithWorkorders().observe(this, new Observer<List<UserWithWorkorders>>() {
            @Override
            public void onChanged(List<UserWithWorkorders> usersWithWorkorders) {
                if (usersWithWorkorders != null && usersWithWorkorders.size() > 0) {

                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                        }
                    });
                }
            }
        });
    }

我究竟做错了什么?如果还有其他代码,你想看,请告诉我。或者换句话说:如果 Dao 查询返回 LiveData 对象,我如何使用 Room 从 SQLLite 数据库中检索我的 android 活动中的对象?

标签: androidsqliteandroid-livedata

解决方案


对于这行代码,你不需要让它返回 observable。

UserWithWorkorders userWithWorkorders = ie4ViewModel.getUserWithWorkorders(username.getText().toString()).getValue();

只需像这样在您的视图模型中声明一个方法。

public UserWithWorkorders getUserWithWorkorders(String value){
//get result from DAO.
}

还要让你的 DAO 方法返回 UserWithWorkorders

现在在您的活动中调用此方法,因为您已经这样做了。

 UserWithWorkorders userWithWorkorders = ie4ViewModel.getUserWithWorkorders(username.getText().toString()).getValue();

完全确保您的数据库有一些数据要返回。


推荐阅读