Android Jetpack ROOM 的Dao返回LiveData
及Bean的区别, LiveData封装与普通没有封装的区别
使用Android Jetpack ROOM时,我们会定义Dao的查询返回,LiveData
定义1 LiveData
@Dao
public interface UserDao {
@Query("SELECT * FROM user_tb")
List<List<User>> getAll();
}
定义2
@Dao
public interface UserDao {
@Query("SELECT * FROM user_tb")
LiveData<List<User>> getAll();
}
LiveData形式生成代码
@Override
public LiveData<List<User>> getAll() {
final String _sql = "SELECT * FROM user_tb";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
return __db.getInvalidationTracker().createLiveData(new String[]{
"user_tb"}, false, new Callable<List<User>>() {
@Override
public List<User> call() throws Exception {
final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
try {
.....
}
return _result;
} finally {
_cursor.close();
}
}
@Override
protected void finalize() {
_statement.release();
}
});
}
对于LiveData形式的生成代码,最基本我们看到了,查询封装在Callable中了,也就是很可能是任务式调用的。实际上,在被观测的时候才会调用。
返回直接数据形式
@Override
public List<User> getAll() {
final String _sql = "SELECT * FROM user_tb";
final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0);
__db.assertNotSuspendingTransaction();
final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
try {
...
_result.add(_item);
}
return _result;
} finally {
_cursor.close();
_statement.release();
}
}
对于直接返回Beans的形式,生成代码中,我们看到这种接口是直接调用查询的,跟使用原生的SQLiteHelper差不多,只是Room框架帮我们生成了。
LiveData封装数据返回的使用
如果这样写,我们获取的数据是LiveData中旧的数据,千万要注意:
LiveData<List<User>> all = userDao.getAll();
if(all !=null){
List<User> value = all.getValue();
//value不是最新数据,可能不是我们想要的
...
}
所以,要使用LiveData形式的数据时,要通过观测者获取数据,否是获取的可能不是最新的数据,因为Callable里的查询根本还没执行。那么我们可以要通过Observer观测数据,当数据发生变化时就可以获取到最新数据。
LiveData正确查询
LiveData<List<User>> all = userDao.getAll();
if(all!=null){
all.observe(getLifeCycleOwner, new Observer<List<User>>() {
@Override
public void onChanged(List<User> value) {
//OK 最新数据
...
}
});
}
直接数据返回的使用
这种使用认为是直接查询即可
List<User> all = userDao.getAll();
if(all !=null && !all.isEmpty()){
//OK 最新数据
...
}
最重要的点在于知道LiveData要通过Oberser观测获取数据。