使用SQLite的RxJava动态更新聊天UI

时间:2016-10-11 08:34:06

标签: android sqlite android-contentprovider rx-java reactive-programming

我有一个聊天应用程序,它使用socket.io与nodejs服务器(由我编写)进行通信。多人可以一对一地互相聊天。该应用的用户界面就像WhatsApp。 Chat Threads可以与Users交换Chat Messages。这些需要存储在SQLite数据库中。

为确保应用程序即使在关闭时也能正常工作,我已在服务中启动了socket.io连接。

当收到新消息时,订单就是

  • 服务解析响应并将其写入SQLite数据库
  • 如果应用已关闭,则会创建通知并向用户显示
  • 如果该应用已启用,并且该用户位于发送新邮件的同一聊天帖子上,则必须更新recyclerView
  • 基本上感觉和whatsapp一样,除了我使用的是socket.io而不是XMPP

我想使用SQLiteRxJava上执行CRUD操作。

SQLiteHelper.Class

public List<ChatMessage> getChatMessagesForThread(String threadName){
    List<ChatMessage>list = new ArrayList<>();
    String query = "Some Query Here";

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor c = db.rawQuery(query, null);

    if (c.moveToFirst()){

        do {
            ChatMessage message = new ChatMessage();
            message.setMessage(c.getString((c.getColumnIndex(CHAT_MESSAGES_KEY_MESSAGE))));
            message.setChatThread(c.getInt(c.getColumnIndex(CHAT_MESSAGES_KEY_CHAT_THREAD)));
            message.setUser(c.getString(c.getColumnIndex(CHAT_MESSAGES_KEY_USER)));
            list.add(message);

        } while (c.moveToNext());

    }else {
        //No such thread exists. Returns null
    }
    c.close();
    return list;
}

Rx Java相关函数

    public static <T> Observable<T> makeObservable(final Callable<T> func) {
        return Observable.create(
                new Observable.OnSubscribe<T>() {
                    @Override
                    public void call(Subscriber<? super T> subscriber) {
                        try {
                            T observed = func.call();
                            if (observed != null) { // to make defaultIfEmpty work
                                subscriber.onNext(observed);
                            }
                            //TODO: DECIDE IF THIS STAYS OR NOT !!!
                            //subscriber.onCompleted();
                        } catch (Exception ex) {
                            subscriber.onError(ex);
                        }
                    }
                }).subscribeOn(Schedulers.io());
    }

@SuppressWarnings("unchecked")
private Callable<List<ChatMessage>> getData(String threadName) {
    return new Callable() {
        public List<ChatMessage> call() {
            return getChatMessagesForThread(String threadName);
        }
    };
}


    public Observable<List<ChatMessage>> getDataObservable(String threadName) {
        return makeObservable(getData(String threadName));
    }

ChatActivity.class

    databaseHelper.getDataObservable(String currentThreadName)
            .subscribe(new Action1<List<ChatMessage>>() {
                @Override
                public void call(List<ChatMessage> chatMessages) {
                    for (ChatMessage message : chatMessages){
                        //Add to list and update recyclerView
                        mAdapter.notifyDatasetChanged();
                    }
                }
            });

问题是,上面的Rxjava调用只执行一次而不是每次执行新的写操作时都会执行。

此函数位于SQLiteHelper类中,并从我的服务中调用

public long writeMessageToDB(ChatMessage message){
    ContentValues values = new ContentValues();
    values.put(CHAT_MESSAGES_KEY_MESSAGE, message.getMessage());
    values.put(CHAT_MESSAGES_KEY_CHAT_THREAD, message.getChatThread());
    values.put(CHAT_MESSAGES_KEY_USER, message.getUser());
    SQLiteDatabase db = this.getWritableDatabase();
    return db.insert(CHAT_MESSAGES_TABLE_NAME, null, values);
}

我已经阅读了有关广告的SQL Delite,但想了解如何使上述工作。请帮忙!

1 个答案:

答案 0 :(得分:0)

是的,你应该使用.defer()运算符,如果你希望每次都能创建observable。

Observable.defer(()-> Observable.just("some arg"))
.subscribeOn(Schedulers.io))
.map(t -> getDataFromDb())
.map(v ->  {
     // handle your result
})
.subscribe(..);