Skip to content

Commit

Permalink
Use viewModelScope for coroutines
Browse files Browse the repository at this point in the history
  • Loading branch information
arcao committed Nov 10, 2019
1 parent 778e4ce commit 3bfe28e
Show file tree
Hide file tree
Showing 17 changed files with 476 additions and 384 deletions.
7 changes: 2 additions & 5 deletions app/src/main/java/com/arcao/geocaching4locus/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import java.util.UUID
class App : Application() {
val accountManager by inject<AccountManager>()

val deviceId: String by lazy {
private val deviceId: String by lazy {
val pref = PreferenceManager.getDefaultSharedPreferences(this)

var value = pref.getString(PrefConstants.DEVICE_ID, null)
Expand Down Expand Up @@ -92,10 +92,6 @@ class App : Application() {

modules(listOf(appModule, geocachingApiModule, locusMapApiModule, feedbackModule))
}
// if (BuildConfig.DEBUG) {
// StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().detectAll().build())
// StrictMode.setVmPolicy(StrictMode.VmPolicy.Builder().detectAll().build())
// }

prepareCrashlytics()

Expand Down Expand Up @@ -150,6 +146,7 @@ class App : Application() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().flush()
} else {
@Suppress("DEPRECATION")
CookieSyncManager.createInstance(this).sync()
}
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/arcao/geocaching4locus/AppModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ internal val appModule = module {
)
}
// update
viewModel { UpdateViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { UpdateViewModel(get(), get(), get(), get(), get(), get(), get(), get(), get()) }
viewModel { UpdateMoreViewModel(get(), get(), get(), get(), get(), get(), get(), get()) }
// web link
viewModel { BookmarkGeocacheWebLinkViewModel(get(), get(), get(), get()) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import com.arcao.geocaching4locus.base.util.invoke
import com.arcao.geocaching4locus.data.account.AccountManager
import com.arcao.geocaching4locus.error.handler.ExceptionHandler
import com.crashlytics.android.Crashlytics
import kotlinx.coroutines.cancelChildren
import kotlinx.coroutines.Job

class LoginViewModel(
private val app: App,
Expand All @@ -25,13 +25,15 @@ class LoginViewModel(
private val accountManager: AccountManager,
dispatcherProvider: CoroutinesDispatcherProvider
) : BaseViewModel(dispatcherProvider) {

val action = Command<LoginAction>()
private var job: Job? = null

fun startLogin() {
if (job.isActive) coroutineContext.cancelChildren()
if (job?.isActive == true) {
job?.cancel()
}

mainLaunch {
job = mainLaunch {
try {
showProgress {
app.clearGeocachingCookies()
Expand All @@ -47,28 +49,34 @@ class LoginViewModel(
}
}

fun finishLogin(input: String) = mainLaunch {
if (input.isBlank()) {
action(LoginAction.Cancel)
return@mainLaunch
fun finishLogin(input: String) {
if (job?.isActive == true) {
job?.cancel()
}

try {
showProgress {
// create account
val account = createAccount(input)
job = mainLaunch {
if (input.isBlank()) {
action(LoginAction.Cancel)
return@mainLaunch
}

val premium = account.isPremium()
try {
showProgress {
// create account
val account = createAccount(input)

// handle analytics and crashlytics
Crashlytics.setBool(CrashlyticsConstants.PREMIUM_MEMBER, premium)
AnalyticsUtil.setPremiumUser(app, premium)
AnalyticsUtil.actionLogin(true, premium)
val premium = account.isPremium()

action(LoginAction.Finish(!premium))
// handle analytics and crashlytics
Crashlytics.setBool(CrashlyticsConstants.PREMIUM_MEMBER, premium)
AnalyticsUtil.setPremiumUser(app, premium)
AnalyticsUtil.actionLogin(true, premium)

action(LoginAction.Finish(!premium))
}
} catch (e: Exception) {
handleException(e)
}
} catch (e: Exception) {
handleException(e)
}
}

Expand All @@ -93,7 +101,7 @@ class LoginViewModel(
fun cancelLogin() {
AnalyticsUtil.actionLogin(success = false, premiumMember = false)

job.cancel()
job?.cancel()
action(LoginAction.Cancel)
}
}
}
36 changes: 12 additions & 24 deletions app/src/main/java/com/arcao/geocaching4locus/base/BaseViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,46 @@ package com.arcao.geocaching4locus.base
import androidx.annotation.StringRes
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.arcao.geocaching4locus.base.coroutine.CoroutinesDispatcherProvider
import com.arcao.geocaching4locus.base.util.runIfIsSuspended
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.coroutines.CoroutineContext

abstract class BaseViewModel(
val dispatcherProvider: CoroutinesDispatcherProvider
) : ViewModel(), CoroutineScope {
val job = Job()
) : ViewModel() {
val progress: MutableLiveData<ProgressState> = MutableLiveData()

// Better to start on main context to minimize cost of switching between computation and main context
// Also it is better to read referenceCode without switching
// If you need more time to do work, switch to computation context
override val coroutineContext: CoroutineContext
get() = dispatcherProvider.main + job

override fun onCleared() {
job.cancel()
super.onCleared()
}

fun <R> mainLaunch(block: suspend CoroutineScope.() -> R) = launch(dispatcherProvider.main) {
block()
}
inline fun <R> mainLaunch(crossinline block: suspend CoroutineScope.() -> R) =
viewModelScope.launch(dispatcherProvider.main) {
block()
}

fun <R> computationLaunch(block: suspend CoroutineScope.() -> R) =
launch(dispatcherProvider.computation) {
inline fun <R> computationLaunch(crossinline block: suspend CoroutineScope.() -> R) =
viewModelScope.launch(dispatcherProvider.computation) {
block()
}

suspend fun <R> mainContext(block: suspend CoroutineScope.() -> R): R =
suspend inline fun <R> mainContext(crossinline block: suspend CoroutineScope.() -> R): R =
withContext(dispatcherProvider.main) {
block()
}

suspend fun <R> computationContext(block: suspend CoroutineScope.() -> R): R =
suspend inline fun <R> computationContext(crossinline block: suspend CoroutineScope.() -> R): R =
withContext(dispatcherProvider.computation) {
block()
}

suspend fun <R> showProgress(
suspend inline fun <R> showProgress(
@StringRes message: Int = 0,
messageArgs: Array<Any>? = null,
progress: Int = 0,
maxProgress: Int = 0,
requestId: Int = 0,
block: suspend CoroutineScope.() -> R
crossinline block: suspend CoroutineScope.() -> R
): R = coroutineScope {

this@BaseViewModel.progress.postValue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import com.arcao.geocaching4locus.base.util.hidePowerManagementWarning
import com.arcao.geocaching4locus.base.util.invoke
import com.arcao.geocaching4locus.data.account.AccountManager
import com.arcao.geocaching4locus.live_map.util.LiveMapNotificationManager
import kotlinx.coroutines.launch
import locus.api.manager.LocusMapManager

class DashboardViewModel(
Expand Down Expand Up @@ -104,7 +103,7 @@ class DashboardViewModel(
liveMapEnabled(newState)
}

fun onPowerSaveWarningConfirmed() = launch {
fun onPowerSaveWarningConfirmed() = mainLaunch {
toggleLiveMap()
}
}
Loading

0 comments on commit 3bfe28e

Please sign in to comment.