Android开发中RxJava-SQLBrite实时刷新UI

android实现数据库实时刷新的方式:

  • ContentProvider+CursorLoaders+SQlite实现数据自动观察者模式
  • Rxjava+SQLBrite+SQLite实现数据自动观察者模式

本篇,这里介绍RxJava+SQLBrite组合方式。

引入RxJava,RxAndroid,SQLBrite库,项目的gradle配置如下:

dependencies {
    .......
    compile 'com.squareup.sqlbrite:sqlbrite:1.1.1'
    compile 'io.reactivex:rxjava:1.3.0'
    compile 'io.reactivex:rxandroid:1.2.1'
}

1.创建数据库:

创建BaseColumn的实现类,存放数据库需要用到的常量配置:

public final class Data implements BaseColumns {
    /**
     * 数据库信息
     */
    public static final String SQLITE_NAME="sqlitePrcactice.db";
    public static final int SQLITE_VERSON=1;
    /**
     * 信息表,及其字段
     */
    public static final String TABLE_NAME="message";
    public static final String COLUMN_CONTENT="content";
    public static final String COLUMN_DATE="date";
    /**
     * 时间字段的格式
     */
    public static final String DATE_FORMAT="YYYY-MM-DD";
    /**
     * 时间字段的降序,采用date函数比较
     */
    public static final String ORDER_BY="date("+COLUMN_DATE+") desc";

}

创建数据库的代码如下:

public class DataHelper extends SQLiteOpenHelper {
    public static final String CREATE_MESSAGE="create table "+
            Data.TABLE_NAME+"("+
            Data._ID+" integer primary key autoincrement,"+
            Data.COLUMN_CONTENT+" text,"+
            Data.COLUMN_DATE+" text"
            +")";

    public DataHelper(Context context) {
        super(context, Data.SQLITE_NAME, null, Data.SQLITE_VERSON);
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_MESSAGE);
    }
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

2. 使用SQLBrite:

若是,不熟悉SQLBrite,可以阅读SQLBrite教程。

先创建一个SQLBrite的管理类:

public class SqlBriteProvider {
    private SqlBrite sqlBrite;
    private BriteDatabase briteDatabase;
    public SqlBriteProvider(Context context){
        this.sqlBrite=providerSqlBrite();
        this.briteDatabase=createDatabase(this.sqlBrite,providerOpenHelper(context));
    }
    /**
     * 创建SQLiteOpenHelper对象
     * @param context
     * @return
     */
    private SQLiteOpenHelper providerOpenHelper(Context context){
        return  new DataHelper(context);
    }

    /**
     *
     * 创建SqlBrite对象
     *
     * @return
     */
    private SqlBrite providerSqlBrite(){
        return  new SqlBrite.Builder().build();
    }
    /**
     * 通过SQLBrite对象和SQLiteOpenHel对象
     * @param sqlBrite
     * @param sqLiteOpenHelper
     * @return
     */
    public BriteDatabase createDatabase(SqlBrite sqlBrite,SQLiteOpenHelper sqLiteOpenHelper){
        BriteDatabase db=sqlBrite.wrapDatabaseHelper(sqLiteOpenHelper, Schedulers.io());
        return db;
    }
    /**
     * 获取到SQLBrite中数据库对象
     * @return
     */
    public BriteDatabase getBriteDatabase() {
        return briteDatabase;
    }
}

接下,来通过BriteDataBase对象来进行SQL操作。

1. 长时间订阅信息,类似CursorLoader

创建一个长时间订阅的查询,返回一个QueryObservable对象。

   private BriteDatabase db;

   private Subscription suscription;

    /**
     * 长时间订阅查询
     */
   private void excuteQuery() {
        //Observable observable
         QueryObservable observable = this.db.createQuery(Data.TABLE_NAME, "select * from message ORDER BY "+Data.ORDER_BY, null);
        suscription = observable.subscribe(new Action1() {
            @Override
            public void call(SqlBrite.Query query) {
                Cursor cursor = query.run();
               //进行解析操作
            }
        });
    }

QueryObservable类实际上是一个提供特定查询方便操作的Observable:

/** An {@link Observable} of {@link Query} which offers query-specific convenience operators. */
public final class QueryObservable extends Observable<Query> {

    .......

 public final  Observable> mapToList(@NonNull Func1 mapper) {
    return lift(Query.mapToList(mapper));
  }
}

2. 插入信息

通过BriteDataBase对象,插入一条数据:

   Message message = new Message();
   message.setContent(content_editext.getText().toString());
   message.setDate(date_editext.getText().toString());
   this.db.insert(Data.TABLE_NAME, ValuesTransform.transformContentValues(message));

当插入成功后,将会通知订阅者,将会调用Cursor cursor = query.run()获取最新的数据源。

3. 取消长时间的订阅

当Activity或Fragment的生命周期改变时候,需要取消订阅,释放资源。

  @Override
  protected void onPause() {
        suscription.unsubscribe();
        super.onPause();
  }

3. 结合RxJava1.x使用:

BriteDataBase对象查询返回的是一个Observable对象,因此可以进行组合,过滤等操作符进行操作,最后切换到UI线程进行更新UI。

private Subscription suscription;
   /**
     * 长时间订阅查询
     */
    private void excuteQuery() {
        //Observable observable
        QueryObservable observable = this.db.createQuery(Data.TABLE_NAME, "select * from message ORDER BY "+Data.ORDER_BY, null);
        suscription = observable
        .observeOn(AndroidSchedulers.mainThread())//订阅者处理信息在UI线程中。
        .subscribe(new Action1() {
            @Override
            public void call(SqlBrite.Query query) {
                Cursor cursor = query.run();
                loadDataToUI(cursor);
            }
        });
    }

    /**
     * 从Cursor获取数据加载到UI上
     *
     * @param cursor
     */
    public void loadDataToUI(Cursor cursor) {
        try {
            if (cursor != null && cursor.moveToFirst()) {
                List list = new ArrayList<>();
                do {
                    list.add(ValuesTransform.transformMessage(cursor));
                } while (cursor.moveToNext());

                //更新UI
                this.adapter.addData(list);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

最后发现,RxJava+SQLBrite实现数据库观察者模式很简单,不需要配置自定义的ContentProvider.

若是,不习惯使用RxJava和SQLBrite,可以阅读上一篇Android原生实现数据库观察者模式

项目效果图如下:

项目代码Github上:https://github.com/13767004362/SQLitePractice

资源参考

  • SQLBrite中文教程: http://blog.csdn.net/hexingen/article/details/71598296
  • SQLBrite: https://github.com/square/sqlbrite
  • RXJava: https://github.com/ReactiveX/RxJava
  • RxAndroid: https://github.com/ReactiveX/RxAndroid

你可能感兴趣的:(Android,应用层开发,Android,热门的框架与第三方SDK,Android,SQLite)