赞
踩
Jetpack Room入门系列:(一)基本介绍
Jetpack Room入门系列:(二)使用DAO读写数据库
Jetpack Room入门系列:(三)实体/数据表关系
Jetpack Room入门系列:(四)内部实现原理
Jetpack Room入门系列:(五)数据库版本升级、数据迁移
Jetpack Room入门系列:(六)配合LiveData等三方库的使用
作为Jetpack生态的成员,Room可以很好地兼容Jetpack的其他组件以及ACC推荐的三方库,例如LiveData、RxJava等。
DAO可以定义LiveData类型的结果,Room内部兼容了LiveData的响应式逻辑。
通常的Query需要命令式的获取结果,LiveData可以让结果的更新可被观察(Observable Queries)。
@Dao
interface UserDao {
@Query("SELECT * FROM users")
fun getAllLiveData(): LiveData<List<User>>
}
当DB的数据发生变化时,Room会更新LiveData:
@Override public LiveData<List<User>> getAllLiveData() { final String _sql = "SELECT * FROM users"; final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 0); return __db.getInvalidationTracker().createLiveData(new String[]{"users"}, false, new Callable<List<User>>() { @Override public List<User> call() throws Exception { final Cursor _cursor = DBUtil.query(__db, _statement, false, null); try { final int _cursorIndexOfUid = CursorUtil.getColumnIndexOrThrow(_cursor, "uid"); final int _cursorIndexOfFirstName = CursorUtil.getColumnIndexOrThrow(_cursor, "first_name"); final int _cursorIndexOfLastName = CursorUtil.getColumnIndexOrThrow(_cursor, "last_name"); final List<User> _result = new ArrayList<User>(_cursor.getCount()); while(_cursor.moveToNext()) { final User _item; final int _tmpUid; _tmpUid = _cursor.getInt(_cursorIndexOfUid); final String _tmpFirstName; _tmpFirstName = _cursor.getString(_cursorIndexOfFirstName); final String _tmpLastName; _tmpLastName = _cursor.getString(_cursorIndexOfLastName); _item = new User(_tmpUid,_tmpFirstName,_tmpLastName); _result.add(_item); } return _result; } finally { _cursor.close(); } } @Override protected void finalize() { _statement.release(); } }); }
__db.getInvalidationTracker().createLiveData()
接受3个参数
computeFunction的call中执行真正的sql查询。当Observer首次订阅LiveData时,或者表数据发生变化时,便会执行到这里。
Room中使用RxJava需要添加以下依赖
dependencies {
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
// RxJava support for Room
implementation "androidx.room:room-rxjava2:$room_version"
}
DAO的返回值类型可以是RxJava2的各种类型:
@Dao
interface UserDao {
@Query("SELECT * from users where uid = :id LIMIT 1")
fun loadUserById(id: Int): Flowable<User>
@Insert
fun insertUsers(vararg users: User): Completable
@Delete
fun deleteAllUsers(users: List<User>): Single<Int>
}
@Override public Completable insertLargeNumberOfUsers(final User... users) { return Completable.fromCallable(new Callable<Void>() { @Override public Void call() throws Exception { __db.beginTransaction(); try { __insertionAdapterOfUser.insert(users); __db.setTransactionSuccessful(); return null; } finally { __db.endTransaction(); } } }); }@Override public Single<Integer> deleteAllUsers(final List<User> users) { return Single.fromCallable(new Callable<Integer>() { @Override public Integer call() throws Exception { int _total = 0; __db.beginTransaction(); try { _total +=__deletionAdapterOfUser.handleMultiple(users); __db.setTransactionSuccessful(); return _total; } finally { __db.endTransaction(); } } }); }@Override public Flowable<User> loadUserById(final int id) { final String _sql = "SELECT * from users where uid = ? LIMIT 1"; final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1); int _argIndex = 1; _statement.bindLong(_argIndex, id); return RxRoom.createFlowable(__db, false, new String[]{"users"}, new Callable<User>() { @Override public User call() throws Exception { //Implementation } @Override protected void finalize() { _statement.release(); } }); }
如上,使用fromCallable{…}创建Completable与Single; RxRoom.createFlowable{…}创建Flowable。call()
里执行真正的sql操作
添加额外依赖:
dependencies {
def room_version = "2.2.5"
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version" // Kotlin Extensions and Coroutines support for Room
implementation "androidx.room:room-ktx:$room_version"
}
为UserDao中的CURD方法添加suspend
@Dao
interface UserDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertUsers(vararg users: User)
@Update
suspend fun updateUsers(vararg users: User)
@Delete
suspend fun deleteUsers(vararg users: User)
@Query("SELECT * FROM users")
suspend fun loadAllUsers(): Array<User>
}
CoroutinesRoom.execute
中进行真正的sql语句,并通过Continuation将callback变为Coroutine的同步调用
@Override public Object insertUsers(final User[] users, final Continuation<? super Unit> p1) { return CoroutinesRoom.execute(__db, true, new Callable<Unit>() { @Override public Unit call() throws Exception { __db.beginTransaction(); try { __insertionAdapterOfUser.insert(users); __db.setTransactionSuccessful(); return Unit.INSTANCE; } finally { __db.endTransaction(); } } }, p1); }
可以对比一下普通版本的insertUsers:
@Override
public void insertUsers(final User... users) {
__db.assertNotSuspendingTransaction();
__db.beginTransaction();
try {
__insertionAdapterOfUser.insert(users);
__db.setTransactionSuccessful();
} finally {
__db.endTransaction();
}
}
区别很明显,添加了suspend后,生成代码中会使用CoroutinesRoom.execute
封装协程。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。