Use coroutines in TaskListViewModel

pull/1043/head
Alex Baker 4 years ago
parent 0c42392c74
commit 2ec60748d3

@ -150,7 +150,8 @@ dependencies {
implementation("androidx.hilt:hilt-work:${Versions.hilt_androidx}")
implementation("androidx.hilt:hilt-lifecycle-viewmodel:${Versions.hilt_androidx}")
implementation("androidx.room:room-runtime:${Versions.room}")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0")
implementation("androidx.room:room-ktx:${Versions.room}")
kapt("androidx.room:room-compiler:${Versions.room}")
implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")

@ -549,12 +549,6 @@
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://developer.android.com/topic/libraries/architecture/index.html
- artifact: org.jetbrains.kotlinx:kotlinx-coroutines-core-common:+
name: kotlinx-coroutines-core-common
copyrightHolder: JetBrains s.r.o.
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://github.com/Kotlin/kotlinx.coroutines
- artifact: org.conscrypt:conscrypt-android:+
name: org.conscrypt:conscrypt-android
copyrightHolder: Android Open Source Project
@ -726,3 +720,9 @@
license: COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
licenseUrl: https://glassfish.dev.java.net/public/CDDLv1.0.html
url: http://jcp.org/aboutJava/communityprocess/final/jsr250/index.html
- artifact: androidx.room:room-ktx:+
name: room-ktx
copyrightHolder: Android Open Source Project
license: The Apache Software License, Version 2.0
licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt
url: https://developer.android.com/topic/libraries/architecture/index.html

@ -1298,20 +1298,6 @@
"url": "https://developer.android.com/topic/libraries/architecture/index.html",
"libraryName": "Android Paging-Common"
},
{
"artifactId": {
"name": "kotlinx-coroutines-core-common",
"group": "org.jetbrains.kotlinx",
"version": "+"
},
"copyrightHolder": "JetBrains s.r.o.",
"copyrightStatement": "Copyright © JetBrains s.r.o. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"url": "https://github.com/Kotlin/kotlinx.coroutines",
"libraryName": "kotlinx-coroutines-core-common"
},
{
"artifactId": {
"name": "conscrypt-android",
@ -1730,6 +1716,20 @@
"normalizedLicense": "cddl1",
"url": "http://jcp.org/aboutJava/communityprocess/final/jsr250/index.html",
"libraryName": "jsr250-api"
},
{
"artifactId": {
"name": "room-ktx",
"group": "androidx.room",
"version": "+"
},
"copyrightHolder": "Android Open Source Project",
"copyrightStatement": "Copyright © Android Open Source Project. All rights reserved.",
"license": "The Apache Software License, Version 2.0",
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt",
"normalizedLicense": "apache2",
"url": "https://developer.android.com/topic/libraries/architecture/index.html",
"libraryName": "room-ktx"
}
]
}

@ -11,12 +11,14 @@ import androidx.sqlite.db.SimpleSQLiteQuery
import com.todoroo.andlib.sql.Criterion
import com.todoroo.andlib.sql.Field
import com.todoroo.andlib.sql.Functions
import com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.api.PermaSql
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.data.Task.Companion.NO_ID
import com.todoroo.astrid.helper.UUIDHelper
import kotlinx.coroutines.runBlocking
import org.tasks.BuildConfig
import org.tasks.data.Place
import org.tasks.data.SubtaskInfo
@ -116,11 +118,15 @@ abstract class TaskDao(private val database: Database) {
@Transaction
open fun fetchTasks(callback: (SubtaskInfo) -> List<String>): List<TaskContainer> {
return fetchTasks(callback, getSubtaskInfo())
return runBlocking {
fetchTasks(callback, getSubtaskInfo())
}
}
@Transaction
open fun fetchTasks(callback: (SubtaskInfo) -> List<String>, subtasks: SubtaskInfo): List<TaskContainer> {
assertNotMainThread()
val start = if (BuildConfig.DEBUG) DateUtilities.now() else 0
val queries = callback.invoke(subtasks)
val db = database.openHelper.writableDatabase
@ -145,11 +151,16 @@ abstract class TaskDao(private val database: Database) {
@RawQuery
abstract fun count(query: SimpleSQLiteQuery): Int
@Query("SELECT EXISTS(SELECT 1 FROM tasks WHERE parent > 0 AND deleted = 0) AS hasSubtasks,"
+ "EXISTS(SELECT 1 FROM google_tasks "
+ " INNER JOIN tasks ON gt_task = _id "
+ " WHERE deleted = 0 AND gt_parent > 0 AND gt_deleted = 0) AS hasGoogleSubtasks")
abstract fun getSubtaskInfo(): SubtaskInfo
@Query("""
SELECT EXISTS(SELECT 1 FROM tasks WHERE parent > 0 AND deleted = 0) AS hasSubtasks,
EXISTS(SELECT 1
FROM google_tasks
INNER JOIN tasks ON gt_task = _id
WHERE deleted = 0
AND gt_parent > 0
AND gt_deleted = 0) AS hasGoogleSubtasks
""")
abstract suspend fun getSubtaskInfo(): SubtaskInfo
@RawQuery(observedEntities = [Place::class])
abstract fun getTaskFactory(

@ -9,11 +9,9 @@ import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.dao.TaskDao
import io.reactivex.Completable
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.BuildConfig
import org.tasks.data.SubtaskInfo
import org.tasks.data.TaskContainer
@ -28,7 +26,6 @@ class TaskListViewModel @ViewModelInject constructor(
private var tasks = MutableLiveData<List<TaskContainer>>()
private var filter: Filter? = null
private var manualSortFilter = false
private val disposable = CompositeDisposable()
private var internal: LiveData<PagedList<TaskContainer>>? = null
fun setFilter(filter: Filter) {
@ -58,26 +55,27 @@ class TaskListViewModel @ViewModelInject constructor(
if (filter == null) {
return
}
disposable.add(
Single.fromCallable { taskDao.getSubtaskInfo() }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
{ subtasks: SubtaskInfo ->
if (manualSortFilter || !preferences.usePagedQueries()) {
performNonPagedQuery(subtasks)
} else {
performPagedListQuery()
}
}) { t: Throwable? -> Timber.e(t) })
try {
viewModelScope.launch {
val subtasks = taskDao.getSubtaskInfo()
if (manualSortFilter || !preferences.usePagedQueries()) {
performNonPagedQuery(subtasks)
} else {
performPagedListQuery()
}
}
} catch (e: Exception) {
Timber.e(e)
}
}
private fun performNonPagedQuery(subtasks: SubtaskInfo) =
disposable.add(
Single.fromCallable { taskDao.fetchTasks({ s: SubtaskInfo? -> getQuery(preferences, filter!!, s!!) }, subtasks) }
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ value: List<TaskContainer> -> tasks.postValue(value) }) { t: Throwable? -> Timber.e(t) })
private suspend fun performNonPagedQuery(subtasks: SubtaskInfo) {
tasks.value = withContext(Dispatchers.IO) {
taskDao.fetchTasks(
{ s: SubtaskInfo? -> getQuery(preferences, filter!!, s!!) },
subtasks)
}
}
private fun performPagedListQuery() {
val queries = getQuery(preferences, filter!!, SubtaskInfo())
@ -97,14 +95,11 @@ class TaskListViewModel @ViewModelInject constructor(
}
if (BuildConfig.DEBUG) {
builder.setFetchExecutor { command: Runnable ->
Completable.fromAction {
AndroidUtilities.assertNotMainThread()
viewModelScope.launch(Dispatchers.IO) {
val start = DateUtilities.now()
command.run()
Timber.d("*** paged list execution took %sms", DateUtilities.now() - start)
}
.subscribeOn(Schedulers.io())
.subscribe()
}
}
internal = builder.build()
@ -112,7 +107,6 @@ class TaskListViewModel @ViewModelInject constructor(
}
override fun onCleared() {
disposable.dispose()
removeObserver()
}

Loading…
Cancel
Save