房间+实时数据调试

Room + Live Data Debugging

我正在尝试创建一个登录功能,它将检查用户名是否存在于 db:-

我需要将实时数据从 Room 数据库成功获取到存储库再到视图模型。下面是代码。它不起作用,但会尝试其中一个建议。

当我从数据库行加载时:-

 UserDetails= dao.loadUserDetails(UserName);
    Log.v("Response", UserDetails.getValue().getToken());

我得到无法调用 Null.....

我对实现这样一个功能的最佳方法是什么以及如何解决这个问题感到困惑。

存储库

public MutableLiveData<String> LoginUser(String UserName,String Password ) {
//
//        rUserDetails.setUsername("nadeem");
//        rUserDetails.setPassword("test");
//        rUserDetails.setToken(AppConstants.PARAMS);
//        rUserDetails.setSid("1234");
//        rUserDetails.setResourcId(Long.valueOf(12134));
//        insert(rUserDetails);


     UserDetails= dao.loadUserDetails(UserName);
    Log.v("Response", UserDetails.getValue().getToken());

    if(UserDetails.getValue()!=null) {
        rUserDetails.setUsername(UserName);
        rUserDetails.setPassword(Password);
        rUserDetails.setToken(AppConstants.PARAMS);
        Observable<MainResponse> mainResponseObserver = mtsAPI.GetSessionID("token/login", AppConstants.PARAMS + "");
        mainResponseObserver.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<MainResponse>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(MainResponse mainResponse) {
                        Log.v("Response", mainResponse.getEid());
                        if (mainResponse.getEid()==null) {
                            msessionId.postValue("Token Error");
                        }
                        else {
                            msessionId.postValue("1");
                            rUserDetails.setSid(mainResponse.getEid());

               rUserDetails.setResourcId(mainResponse.getUserVO().getBact());
                            insert(rUserDetails);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
   }
   else {
        msessionId.postValue("E");
    }
    return msessionId;

}

我卡在了检查用户数据是否在 Room DB 中的部分。如果在房间数据库中,它 returns UserDetails 这是一个可变的实时数据。

我已经测试了数据库。当我分别测试它们时,它插入成功并成功读取。

@Dao
public interface UserLoginDetailsDao {
    @Insert(onConflict = REPLACE)
    void save(UserLoginDetails user);
    @Query("SELECT sid, Username, Password,ResourcId,Token  FROM 
    UserLogins_tbl 
    WHERE Username = :userId")
    LiveData<UserLoginDetails> loadUserDetails(String userId);
}

使用上面的代码我无法调用 Null.... UserDetails.getvalue.getToken

您正在使用 LiveData 获取在此 Dao 方法中声明的用户详细信息

LiveData<UserLoginDetails> loadUserDetails(String userId);

不能 直接调用 LiveData 上的 getValue() 并且 期望 获取当前值。 LiveData 需要首先计算一个观察者。在这种情况下,不会同步获取值。 您可以找到相同的问题 here

要使用 LiveData,您需要通过像 Activity 一样传递 LifecycleOwner 来观察变化,就像他们在架构组件示例中给出的那样 - ProductFragment

// Observe product data
model.getObservableProduct().observe(this, new Observer<ProductEntity>() {
    @Override
    public void onChanged(@Nullable ProductEntity productEntity) {
        model.setProduct(productEntity);
    }
});

如果你想要没有观察者的值,你可以像这样将 return 类型更改为非 LiveData

UserLoginDetails loadUserDetails(String userId);

在这种情况下,您不能在 main 线程上调用此方法。您需要在后台线程上调用此数据库 synchronous 操作方法,例如使用 Schedulers.io() 线程使用 RxJava.

可能的解决方案是将 RxJava 与用户数据的 return Flowable 空间一起使用,例如架构组件示例中所示 - UserDao.java

将您的 loadUserDetails 更改为 return Flowable

Flowable<UserLoginDetails?> loadUserDetails(String userId);

订阅 Flowable 赞 - UserViewModel.java

// Map the result to desired format
// Using RxJava operators to perform checks
// If user is null or not
public void checkUserExists(String userId) {
    dao.loadUserDetails(userId)
        .map(new Function<UserLoginDetails, Boolean>() {
            @Override
            public Boolean apply(UserLoginDetails userLoginDetails) throws Exception {
                if(userLoginDetails == null){
                    return false;
                } else {
                    return true;
                }
            }
        })
        .subscribe(getObserver());
}

所以当你得到 Flowable 时,你可以应用各种运算符来检查你想要的 条件 并且可以转换这个 streamboolean 可观察值取决于您的条件。对于这个特定的用例,这将是非常容易和 可维护的 方法。