From 477ec3e1823df0ca245e9e0d469da8cf4958c774 Mon Sep 17 00:00:00 2001 From: Canny Date: Fri, 7 Oct 2022 19:17:23 +0300 Subject: [PATCH] feat: remove observer when ViewModel is cleared --- .../manager/patcher/worker/PatcherWorker.kt | 2 +- .../manager/ui/screen/PatchingScreen.kt | 4 +- .../ui/viewmodel/PatchingScreenViewModel.kt | 47 +++++++++---------- 3 files changed, 27 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt b/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt index 693b52a..388f8b3 100644 --- a/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt +++ b/app/src/main/java/app/revanced/manager/patcher/worker/PatcherWorker.kt @@ -149,7 +149,7 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val Logging.log += "Merging integrations\n" patcher.addFiles(listOf(integrations)) {} - Logging.log += "Applying ${patches.size} patch(es)" + Logging.log += "Applying ${patches.size} patch(es)\n" patcher.executePatches().forEach { (patch, result) -> if (result.isFailure) { diff --git a/app/src/main/java/app/revanced/manager/ui/screen/PatchingScreen.kt b/app/src/main/java/app/revanced/manager/ui/screen/PatchingScreen.kt index 8996d17..326e8ed 100644 --- a/app/src/main/java/app/revanced/manager/ui/screen/PatchingScreen.kt +++ b/app/src/main/java/app/revanced/manager/ui/screen/PatchingScreen.kt @@ -11,6 +11,7 @@ import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Done import androidx.compose.material3.* import androidx.compose.runtime.* +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow @@ -30,7 +31,7 @@ fun PatchingScreen( navigator: BackstackNavigator, vm: PatchingScreenViewModel = getViewModel() ) { - var patching by mutableStateOf(false) + var patching by rememberSaveable {mutableStateOf(false)} val scrollState = rememberScrollState() val coroutineScope = rememberCoroutineScope() LaunchedEffect(patching) { @@ -96,6 +97,7 @@ fun PatchingScreen( ) Text(text = "Completed!", fontSize = 30.sp) } + PatchingScreenViewModel.Status.Idle -> {} } } } diff --git a/app/src/main/java/app/revanced/manager/ui/viewmodel/PatchingScreenViewModel.kt b/app/src/main/java/app/revanced/manager/ui/viewmodel/PatchingScreenViewModel.kt index edb4d7c..da215de 100644 --- a/app/src/main/java/app/revanced/manager/ui/viewmodel/PatchingScreenViewModel.kt +++ b/app/src/main/java/app/revanced/manager/ui/viewmodel/PatchingScreenViewModel.kt @@ -1,59 +1,58 @@ package app.revanced.manager.ui.viewmodel import android.app.Application -import android.util.Log import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue +import androidx.lifecycle.Observer import androidx.lifecycle.ViewModel import androidx.work.* import app.revanced.manager.patcher.worker.PatcherWorker -import app.revanced.manager.util.tag class PatchingScreenViewModel(val app: Application) : ViewModel() { - // create worker - private val patcherWorker = OneTimeWorkRequest.Builder(PatcherWorker::class.java) + private val patcherWorker = OneTimeWorkRequest.Builder(PatcherWorker::class.java) // create Worker .setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST) .setInputData( Data.Builder() .build() ).build() - var status by mutableStateOf(Status.Patching) + private val liveData = WorkManager.getInstance(app).getWorkInfoByIdLiveData(patcherWorker.id) // get LiveData + + private val observer = Observer { workInfo: WorkInfo -> // observer for observing patch status + status = when (workInfo.state) { + WorkInfo.State.RUNNING -> Status.Patching + WorkInfo.State.SUCCEEDED -> Status.Success + WorkInfo.State.FAILED -> Status.Failure + else -> Status.Idle + } + } + + var status by mutableStateOf(Status.Idle) sealed class Status { + object Idle : Status() object Patching : Status() object Success : Status() object Failure : Status() } - fun startPatcher() { - cancelPatching() // cancel existing patching process - Logging.log = "" // and clear logs - + cancelPatching() // cancel patching if its still running WorkManager.getInstance(app) - .enqueueUniqueWork("patching", ExistingWorkPolicy.KEEP, patcherWorker) - status = Status.Patching // set status - Log.d(tag, "Created worker.") - - val liveData = WorkManager.getInstance(app).getWorkInfoByIdLiveData(patcherWorker.id) // live data for observing - - liveData.observeForever { workInfo: WorkInfo -> // shitty solution but it works - status = when (workInfo.state) { - WorkInfo.State.SUCCEEDED -> Status.Success - WorkInfo.State.FAILED -> Status.Failure - else -> Status.Patching - } - } - - Log.d(tag, "Worker finished.") + .enqueueUniqueWork("patching", ExistingWorkPolicy.KEEP, patcherWorker) // enqueue patching process + liveData.observeForever(observer) // start observing patch status } private fun cancelPatching() { WorkManager.getInstance(app).cancelWorkById(patcherWorker.id) } + + override fun onCleared() { + super.onCleared() + liveData.removeObserver(observer) // remove observer when ViewModel is destroyed + } } object Logging {