mirror of
https://github.com/iSoron/uhabits.git
synced 2025-12-06 09:08:52 -06:00
SyncManager: Switch to coroutines
This commit is contained in:
@@ -6,7 +6,8 @@ TARGET_SDK_VERSION = 29
|
|||||||
COMPILE_SDK_VERSION = 29
|
COMPILE_SDK_VERSION = 29
|
||||||
|
|
||||||
DAGGER_VERSION = 2.25.4
|
DAGGER_VERSION = 2.25.4
|
||||||
KOTLIN_VERSION = 1.3.61
|
KOTLIN_VERSION = 1.4.0
|
||||||
|
KX_COROUTINES_VERSION = 1.4.2
|
||||||
SUPPORT_LIBRARY_VERSION = 28.0.0
|
SUPPORT_LIBRARY_VERSION = 28.0.0
|
||||||
AUTO_FACTORY_VERSION = 1.0-beta6
|
AUTO_FACTORY_VERSION = 1.0-beta6
|
||||||
BUILD_TOOLS_VERSION = 4.0.0
|
BUILD_TOOLS_VERSION = 4.0.0
|
||||||
|
|||||||
@@ -92,6 +92,8 @@ dependencies {
|
|||||||
implementation "com.google.code.gson:gson:2.8.5"
|
implementation "com.google.code.gson:gson:2.8.5"
|
||||||
implementation "com.google.code.findbugs:jsr305:3.0.2"
|
implementation "com.google.code.findbugs:jsr305:3.0.2"
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$KOTLIN_VERSION"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$KOTLIN_VERSION"
|
||||||
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$KX_COROUTINES_VERSION"
|
||||||
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$KX_COROUTINES_VERSION"
|
||||||
implementation "androidx.constraintlayout:constraintlayout:2.0.0-beta4"
|
implementation "androidx.constraintlayout:constraintlayout:2.0.0-beta4"
|
||||||
implementation 'com.google.zxing:core:3.4.1'
|
implementation 'com.google.zxing:core:3.4.1'
|
||||||
implementation "io.ktor:ktor-client-core:$KTOR_VERSION"
|
implementation "io.ktor:ktor-client-core:$KTOR_VERSION"
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
package org.isoron.uhabits.activities.habits.list
|
package org.isoron.uhabits.activities.habits.list
|
||||||
|
|
||||||
import android.os.*
|
import android.os.*
|
||||||
|
import kotlinx.coroutines.*
|
||||||
import org.isoron.uhabits.*
|
import org.isoron.uhabits.*
|
||||||
import org.isoron.uhabits.activities.*
|
import org.isoron.uhabits.activities.*
|
||||||
import org.isoron.uhabits.activities.habits.list.views.*
|
import org.isoron.uhabits.activities.habits.list.views.*
|
||||||
@@ -40,6 +41,7 @@ class ListHabitsActivity : HabitsActivity() {
|
|||||||
lateinit var prefs: Preferences
|
lateinit var prefs: Preferences
|
||||||
lateinit var midnightTimer: MidnightTimer
|
lateinit var midnightTimer: MidnightTimer
|
||||||
lateinit var syncManager: SyncManager
|
lateinit var syncManager: SyncManager
|
||||||
|
private val scope = CoroutineScope(Dispatchers.Main)
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -61,7 +63,9 @@ class ListHabitsActivity : HabitsActivity() {
|
|||||||
midnightTimer.onPause()
|
midnightTimer.onPause()
|
||||||
screen.onDettached()
|
screen.onDettached()
|
||||||
adapter.cancelRefresh()
|
adapter.cancelRefresh()
|
||||||
|
scope.launch {
|
||||||
syncManager.onPause()
|
syncManager.onPause()
|
||||||
|
}
|
||||||
super.onPause()
|
super.onPause()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +74,9 @@ class ListHabitsActivity : HabitsActivity() {
|
|||||||
screen.onAttached()
|
screen.onAttached()
|
||||||
rootView.postInvalidate()
|
rootView.postInvalidate()
|
||||||
midnightTimer.onResume()
|
midnightTimer.onResume()
|
||||||
|
scope.launch {
|
||||||
syncManager.onResume()
|
syncManager.onResume()
|
||||||
|
}
|
||||||
taskRunner.run {
|
taskRunner.run {
|
||||||
AutoBackup(this@ListHabitsActivity).run()
|
AutoBackup(this@ListHabitsActivity).run()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import io.ktor.client.engine.android.*
|
|||||||
import io.ktor.client.features.*
|
import io.ktor.client.features.*
|
||||||
import io.ktor.client.features.json.*
|
import io.ktor.client.features.json.*
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
|
import kotlinx.coroutines.*
|
||||||
|
|
||||||
data class RegisterReponse(val key: String)
|
data class RegisterReponse(val key: String)
|
||||||
data class GetDataVersionResponse(val version: Long)
|
data class GetDataVersionResponse(val version: Long)
|
||||||
@@ -35,16 +36,16 @@ class RemoteSyncServer(
|
|||||||
}
|
}
|
||||||
) : AbstractSyncServer {
|
) : AbstractSyncServer {
|
||||||
|
|
||||||
override suspend fun register(): String {
|
override suspend fun register(): String = Dispatchers.IO {
|
||||||
try {
|
try {
|
||||||
val response: RegisterReponse = httpClient.post("$baseURL/register")
|
val response: RegisterReponse = httpClient.post("$baseURL/register")
|
||||||
return response.key
|
return@IO response.key
|
||||||
} catch(e: ServerResponseException) {
|
} catch(e: ServerResponseException) {
|
||||||
throw ServiceUnavailable()
|
throw ServiceUnavailable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun put(key: String, newData: SyncData) {
|
override suspend fun put(key: String, newData: SyncData) = Dispatchers.IO {
|
||||||
try {
|
try {
|
||||||
val response: String = httpClient.put("$baseURL/db/$key") {
|
val response: String = httpClient.put("$baseURL/db/$key") {
|
||||||
header("Content-Type", "application/json")
|
header("Content-Type", "application/json")
|
||||||
@@ -57,9 +58,10 @@ class RemoteSyncServer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getData(key: String): SyncData {
|
override suspend fun getData(key: String): SyncData = Dispatchers.IO {
|
||||||
try {
|
try {
|
||||||
return httpClient.get("$baseURL/db/$key")
|
val data: SyncData = httpClient.get("$baseURL/db/$key")
|
||||||
|
return@IO data
|
||||||
} catch (e: ServerResponseException) {
|
} catch (e: ServerResponseException) {
|
||||||
throw ServiceUnavailable()
|
throw ServiceUnavailable()
|
||||||
} catch (e: ClientRequestException) {
|
} catch (e: ClientRequestException) {
|
||||||
@@ -67,10 +69,10 @@ class RemoteSyncServer(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun getDataVersion(key: String): Long {
|
override suspend fun getDataVersion(key: String): Long = Dispatchers.IO {
|
||||||
try {
|
try {
|
||||||
val response: GetDataVersionResponse = httpClient.get("$baseURL/db/$key/version")
|
val response: GetDataVersionResponse = httpClient.get("$baseURL/db/$key/version")
|
||||||
return response.version
|
return@IO response.version
|
||||||
} catch(e: ServerResponseException) {
|
} catch(e: ServerResponseException) {
|
||||||
throw ServiceUnavailable()
|
throw ServiceUnavailable()
|
||||||
} catch (e: ClientRequestException) {
|
} catch (e: ClientRequestException) {
|
||||||
|
|||||||
@@ -51,13 +51,11 @@ class SyncManager @Inject constructor(
|
|||||||
commandRunner.addListener(this)
|
commandRunner.addListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sync() {
|
suspend fun sync() {
|
||||||
if(!preferences.isSyncEnabled) {
|
if (!preferences.isSyncEnabled) {
|
||||||
Log.i("SyncManager", "Device sync is disabled. Skipping sync")
|
Log.i("SyncManager", "Device sync is disabled. Skipping sync")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
taskRunner.execute {
|
|
||||||
runBlocking {
|
|
||||||
try {
|
try {
|
||||||
Log.i("SyncManager", "Starting sync (key: ${preferences.syncKey})")
|
Log.i("SyncManager", "Starting sync (key: ${preferences.syncKey})")
|
||||||
fetchAndMerge()
|
fetchAndMerge()
|
||||||
@@ -69,13 +67,10 @@ class SyncManager @Inject constructor(
|
|||||||
preferences.syncKey = ""
|
preferences.syncKey = ""
|
||||||
preferences.encryptionKey = ""
|
preferences.encryptionKey = ""
|
||||||
}
|
}
|
||||||
return@runBlocking
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun upload() {
|
suspend fun upload() {
|
||||||
if(!dirty) {
|
if (!dirty) {
|
||||||
Log.i("SyncManager", "Database not dirty. Skipping upload.")
|
Log.i("SyncManager", "Database not dirty. Skipping upload.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -101,14 +96,19 @@ class SyncManager @Inject constructor(
|
|||||||
currVersion = data.version + 1
|
currVersion = data.version + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onResume() {
|
suspend fun onResume() {
|
||||||
sync()
|
sync()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onPause() {
|
suspend fun onPause() {
|
||||||
sync()
|
sync()
|
||||||
}
|
}
|
||||||
override fun onSyncEnabled() = sync()
|
|
||||||
|
override fun onSyncEnabled() {
|
||||||
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
|
sync()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCommandExecuted(command: Command?, refreshKey: Long?) {
|
override fun onCommandExecuted(command: Command?, refreshKey: Long?) {
|
||||||
dirty = true
|
dirty = true
|
||||||
|
|||||||
Reference in New Issue
Block a user