我正在尝试创建一个登录功能,该功能将检查用户名是否存在于数据库中:-
我需要成功地将实时数据从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中的部分上。如果在房间DB中,它将返回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);
}
使用上述代码,我无法在UserDetails.getvalue.getToken上调用Null ....
答案 0 :(得分:1)
您正在使用LiveData
来获取此Dao方法中声明的用户详细信息
LiveData<UserLoginDetails> loadUserDetails(String userId);
您不能直接在LiveData
上调用getValue()并期望以获取当前值。 LiveData
首先需要计算观察者。在这种情况下,不会同步获取值。
您可以找到相同的问题here
要使用LiveData
,您需要通过像LifecycleOwner
一样传递Activity
来观察更改,就像在体系结构组件示例-ProductFragment
// Observe product data
model.getObservableProduct().observe(this, new Observer<ProductEntity>() {
@Override
public void onChanged(@Nullable ProductEntity productEntity) {
model.setProduct(productEntity);
}
});
如果您希望没有观察者的值,可以将返回类型更改为非LiveData
,
UserLoginDetails loadUserDetails(String userId);
在这种情况下,您不能在主线程上调用此方法。您需要在后台线程上调用此数据库同步操作方法,例如使用Schedulers.io()
线程和使用RxJava
的线程。
可能的解决方案是将RxJava与Room一起使用以返回Flowable
用户数据,例如,如体系结构组件示例-UserDao.java
更改您的loadUserDetails以返回Flowable
Flowable<UserLoginDetails?> loadUserDetails(String userId);
像-UserViewModel.java一样订阅Flowable
// 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
时,可以应用各种运算符检查所需的条件,并将此流转换为布尔值 >可观察的价值取决于您的条件。对于这种特殊的用例,这将是非常容易且可维护的方法。