AndroidRoom使用以及配合RxJava

AndroidRoom使用以及配合RxJava

2023年7月25日发(作者:)

AndroidRoom使⽤以及配合RxJava最近要做的项⽬要涉及到数据库,准备使⽤⾕歌新出的架构组件Room,于是学习学习,记录⼀下。##1.引⼊⾸先在project的gradle⽂件中添加 Google Maven 仓库```allprojects { repositories { jcenter() google() }}```然后在APP的gradle⽂件中添加依赖``` // Room (use 1.1.0-beta2 for latest beta) implementation ":runtime:1.0.0" annotationProcessor ":compiler:1.0.0"```##2.三⼤组成部分Room由三⼤部分组成1. Entity:数据库中表对应的Java实体2. DAO:操作数据库的⽅法3. Database:创建数据库###2.1EntityEntity就是⼀般的Java实体类这⾥只涉及到@Entity、 @PrimaryKey,2个注解。其实有其他好多注解,⽐如 @ColumnInfo(列名)、 @ForeignKey(外键)、@Index(索引)等等,具体⽤法还是看官⽅⽂档吧。```@Entitypublic class UserEntity { @PrimaryKey(autoGenerate = true) private int uid; private String name; private String address; public String getAddress() { return address; } public void setAddress(String address) { s = address; } public int getUid() { return uid; } public void setUid(int uid) { = uid; } public String getName() { return name; } public void setName(String name) { = name; } @Override public String toString() { return "UserEntity{" + "uid=" + uid + ", name='" + name + ''' + ", address='" + address + ''' + '}'; }}```##2.2 DAODAO的话就是创建⼀些访问数据库的⽅法通过注解的⽅式实现增(@Insert)删(@Delete)改(@Update)查(@Query)可以通过“:xxx”的⽅式引⼊参数```@Daopublic interface UserDao { @Insert void insert(UserEntity userEntity); @Insert void insertAll(List userEntities); @Delete void delete(UserEntity userEntity); @Delete void deleteAll(List userEntities); @Update void update(UserEntity userEntity); @Query("SELECT * FROM UserEntity") List getAll(); public static AppDatabase getInstance(final Context context, final AppExecutors executors) { if (sInstance == null) { synchronized () { if (sInstance == null) { sInstance = buildDatabase(licationContext(), executors); DatabaseCreated(licationContext()); } } } return sInstance; } /** * Build the database. {@link Builder#build()} only sets up the database configuration and * creates a new instance of the database. * The SQLite database is only created when it's accessed for the first time. */ private static AppDatabase buildDatabase(final Context appContext, final AppExecutors executors) { return seBuilder(appContext, , DATABASE_NAME) .addCallback(new Callback() { @Override public void onCreate(@NonNull SupportSQLiteDatabase db) { te(db); ().execute(() -> { // Add a delay to simulate a long-running operation addDelay(); // Generate the data for pre-population AppDatabase database = tance(appContext, executors); List users = teUsers(); insertData(database, users); // notify that the database was created and it's ready to be used abaseCreated(); }); } })

.build(); } /** * Check whether the database already exists and expose it via {@link #getDatabaseCreated()} */ private void updateDatabaseCreated(final Context context) { if (abasePath(DATABASE_NAME).exists()) { setDatabaseCreated(); } } private static void addDelay() { try { (4000); } catch (InterruptedException ignored) { } } private static void insertData(final AppDatabase database, final List users) { ransaction(() -> { o().insertAll(users); }); } public LiveData getDatabaseCreated() { return mIsDatabaseCreated; } private void setDatabaseCreated(){ lue(true); }}数据⽣成⼯具:/** * Generates data to pre-populate the database */public class DataGenerator { private static final String[] NAME = new String[]{ "Special edition", "New", "Cheap", "Quality", "Used"}; private static final String[] ADDRESS = new String[]{ "Three-headed Monkey", "Rubber Chicken", "Pint of Grog", "Monocle"}; public static List generateUsers() { List userEntities = new ArrayList<>(); for (int i = 0; i < ; i++) { UserEntity product = new UserEntity(); e(NAME[ i ]); ress(ADDRESS [ i ]); (product); } return userEntities; }}```##3数据库升级数据库升级要创建Migration类,在migrate⽅法中添加改变的SQL语句,然后version加1```static final Migration MIGRATION_1_2 = new Migration(1, 2) { @Override public void migrate(SupportSQLiteDatabase database) { L("ALTER TABLE UserEntity " + " ADD COLUMN address TEXT"); } };在build()之前添加addMigrationsreturn seBuilder(appContext, , DATABASE_NAME) .addMigrations(MIGRATION_1_2) .build();@Database(entities = {},version = 2)```##4访问数据库三⼤组件创建好,你就可以使⽤数据库啦```数据库和线程池⼯具(AppExecutors)我都放在⾃定义的Application当中去获取了。其实可以再创建⼀个Repository仓库类,⾥⾯放本地数据库的访问和⽹络的访问,更好地管理数据来源。private List mUserList; tance().getAppExecutors().diskIO().execute(new Runnable() { @Override public void run() { mUserList = tance().getDatabase().userDao().getAll(); } });```MyApplication:```public class MyApplication extends Application{ private static MyApplication app; private AppExecutors mAppExecutors; @Override public void onCreate() { te(); app = this; mAppExecutors = new AppExecutors(); Adapter(new AndroidLogAdapter()); } public static MyApplication getInstance() { return app; } public AppDatabase getDatabase() { return tance(this, mAppExecutors); } public AppExecutors getAppExecutors(){ return mAppExecutors; }}```AppExecutors:```/** * Global executor pools for the whole application. *

* Grouping tasks like this avoids the effects of task starvation (e.g. disk reads don't wait behind * webservice requests). */public class AppExecutors { private final Executor mDiskIO; private final Executor mNetworkIO; private final Executor mMainThread; private AppExecutors(Executor diskIO, Executor networkIO, Executor mainThread) { O = diskIO; rkIO = networkIO; hread = mainThread; } public AppExecutors() { this(gleThreadExecutor(), edThreadPool(3), new MainThreadExecutor()); } public Executor diskIO() { return mDiskIO; } public Executor networkIO() { return mNetworkIO; } public Executor mainThread() { return mMainThread; } private static class MainThreadExecutor implements Executor { private Handler mainThreadHandler = new Handler(nLooper()); @Override public void execute(@NonNull Runnable command) { (command); } }}```这样Room就⾃动为我们创建好了可观察的对象,我们这样使⽤就好了```private List mUserList; tance().getDatabase().userDao().getAll() .subscribeOn(()) .observeOn(read()) .subscribe(new Consumer>() { @Override public void accept(List userEntities) throws Exception { mUserList = userEntities; } }, new Consumer() { @Override public void accept(Throwable throwable) throws Exception {

} });```Consumer 是RxJava观察者的简写⽅式```ibe( new Consumer() {//相当于onNext @Override public void accept(String s) throws Exception { } }, new Consumer() {//相当于onError @Override public void accept(Throwable throwable) throws Exception { } }, new Action() {//相当于onComplete,注意这⾥是Action @Override public void run() throws Exception { } }, new Consumer() {//相当于onSubscribe @Override public void accept(Subscription subscription) throws Exception { } });```这⾥我有个疑问,如果我不⽤简写的⽅式,只能触发onSubscribe回调,在onNext回调中获取不到查询数据库的结果。(试了下,Single类型不会)希望有⼤神能帮我解惑``` tance().getDatabase().userDao().getAll() .subscribeOn(()) .observeOn(read()) .subscribe(new FlowableSubscriber>() { @Override public void onSubscribe(Subscription s) {

} @Override public void onNext(List userEntities) { //获取不到 mUserList = userEntities; } @Override public void onError(Throwable t) { } @Override public void onComplete() { } });```有⼀点值得**注意**的是:**如果使⽤Flowable,那么每当Flowable包裹的对象改变时,Flowable将⾃动发射,也就是⾃动执⾏accept回调。**这回没有⾃动发射了,也正常了,是不是数据库操作都应该使⽤Single⽽不是Flowable呢?希望⼤家讨论⼀下。------------------------------------分割线---------------------------------------------关于上⾯【这⾥我有个疑问,如果我不⽤简写的⽅式,只能触发onSubscribe回调,在onNext回调中获取不到查询数据库的结果。(试了下,Single类型不会)】这个问题:其实是RxJava2.0后的⼀点⼩区别:出现了2种观察者模式1. Observable(被观察者)/Observer(观察者)2. Flowable(被观察者)/Subscriber(观察者)Room⽀持的3种RxJava对象中,Maybe和Single 属于前⼀种,Flowable 属于后⼀种。

发布者:admin,转转请注明出处:http://www.yc00.com/web/1690219574a316865.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信