如何创建一个Observable of cursor

时间:2017-03-19 16:07:44

标签: sqlite rx-java rx-android

我有一个SQLite查询返回的游标,我想知道创建一个Observable的正确方法,它会发出游标中的每一行。

我按如下方式创建了光标observable,请检查这是否正确:

 Observable<Cursor> cursorObservable = Observable.create(new ObservableOnSubscribe<Cursor>() {
            @Override
            public void subscribe(ObservableEmitter<Cursor> e) throws Exception {
                SQLDbHelper dbHelper = SQLDbHelper.getInstance(ctx);
                SQLiteDatabase db = dbHelper.getReadableDatabase();
                Cursor cursor = db.rawQuery("select * from " + MoviesContract.MovieEntry.TABLE_NAME, null);
                if (cursor != null) {
                    try {
                        while (cursor.moveToNext() && !e.isDisposed()) {
                            e.onNext(cursor);
                        }
                    } catch (Exception exception) {
                        e.onError(exception);
                    } finally {
                        cursor.close();
                    }

                }
                if (!e.isDisposed()) {
                    e.onComplete();
                }
            }
        });

1 个答案:

答案 0 :(得分:2)

我感谢您将更好的结果将行包装到Map中并将其传递给流,而不是传递光标本身。

class SimpleTest {
    @Test
    fun testCursorStream() {
        val cursor = fakeCursor()
        val stream = getCursorStream(cursor)

        stream.subscribe {
            Log.d("Test", it.entries.toString())
        }
    }

    private fun fakeCursor() : Cursor {
        val columns = arrayOf("id", "name", "age")
        val cursor = MatrixCursor(columns)
        val row1 = arrayOf(1, "Rodrigo", 26L)
        val row2 = arrayOf(2, "Lucas", 23L)
        val row3 = arrayOf(3, "Alan", 26L)
        cursor.addRow(row1)
        cursor.addRow(row2)
        cursor.addRow(row3)
        return cursor
    }

    private fun getCursorStream(cursor: Cursor) : Observable<Map<String, Any?>> {
        return Observable.create<Map<String, Any?>> {
            try {
                if (!cursor.moveToFirst()) {
                    it.onCompleted()
                    return@create
                }

                val row = HashMap<String, Any?>()

                do {
                    val lastColumnIndex = cursor.columnCount - 1

                    for (index in 0..lastColumnIndex) {
                        val name = cursor.getColumnName(index)
                        val type = cursor.getType(index)

                        when (type) {
                            Cursor.FIELD_TYPE_STRING -> row.put(name, cursor.getString(index))
                            Cursor.FIELD_TYPE_BLOB -> row.put(name, cursor.getBlob(index))
                            Cursor.FIELD_TYPE_FLOAT -> row.put(name, cursor.getFloat(index))
                            Cursor.FIELD_TYPE_INTEGER -> row.put(name, cursor.getInt(index))
                            Cursor.FIELD_TYPE_NULL -> row.put(name, null)
                        }
                    }

                    it.onNext(row)
                } while (cursor.moveToNext())

                it.onCompleted()
            } catch (e: Exception) {
                it.onError(e)
            }
        }
    }
}

希望它有所帮助。