my code was
val cursor = getApplication<Application>().contentResolver.query(
asksContract.CONTENT_URI, projection, null, null, sortOrder
)
dbCursor.setValue(cursor!!) // Update on different thread
And I changed it to
viewModelScope.launch(Dispatchers.IO) {
val cursor = getApplication<Application>().contentResolver.query(
TasksContract.CONTENT_URI, projection, null, null, sortOrder
)
dbCursor.setValue(cursor!!)
}
I think this is correct, no need to postValues as ime no longer in the main thread. Is this correct?
Also I am still getting warning
This `Cursor` should be freed up after use with `#close()`
Which makes sense, so should I
dbCursor.close()
after I setValue? or do I just ignore the error? The code is loading the data in a viewModel, the cursor is LiveData and there is an observer. I think maybe not as the cursor is still being used by the Recyclerview.
PS I setValues causes
java.lang.IllegalStateException: Cannot invoke setValue on a background thread
But starting a new thread withing the coroutine seems a bit silly, what have I missed?
The whole function is
private fun loadTasks() {
val func = "loadTasks"
Log.d(TAG, func)
val projection = arrayOf(
TasksContract.Columns.ID,
TasksContract.Columns.TASK_NAME,
TasksContract.Columns.TASK_DESCRIPTION,
TasksContract.Columns.TASK_SORT_ORDER
)
val sortOrder =// set sortOrder so cursor is in correct order
"${TasksContract.Columns.TASK_SORT_ORDER}, ${TasksContract.Columns.TASK_NAME}"
viewModelScope.launch(Dispatchers.IO) {
val cursor =
getApplication<Application>().contentResolver.query(
TasksContract.CONTENT_URI, projection, null, null, sortOrder
)
dbCursor.postValue(cursor!!) // runs setValue via Handler in MainThread
}
Log.d(TAG, "$func done")
}