2017-03-19 57 views
1

我有一个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(); 
       } 
      } 
     }); 
+0

请详细说明,'每一行'是什么意思?请给出例子与普通的Android代码 – yosriz

+0

尝试使用这个库https://github.com/pushtorefresh/storio或看看他们如何与sqlite – shmakova

+0

@yosriz由SQLite查询返回的游标包含指针行,所以我想可观察的,依次发出这些行,直到光标耗尽为止。 –

回答

2

我感谢你会有更好的效果包裹行成地图,并使其通过流不是传递光标本身。

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() 
        [email protected] 
       } 

       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) 
      } 
     } 
    } 
} 

希望它有帮助。

+0

实际上在observable中返回游标没有工作。而不是返回游标,我像你一样处理游标和返回的地图对象,它工作正常。谢谢 –

+0

@BharatMukkala你可以检查我的答案是否是最适合你的答案吗? –

+1

在你的循环'while(cursor.moveToNext())'你也需要检查订阅是否没有被处置。否则,你可能会不必要地循环。 –