Можно ли использовать sharedPrefrence с Coroutine kotlin? - PullRequest
2 голосов
/ 24 октября 2019

Я ввел sharedPreference в ViewModel.

Могу ли я использовать ресурсы, специфичные для Android, при встраивании области Coroutine, которая автоматически приостанавливается, когда ViewModel теряет область. Область запуска viewModel

CoroutineScope отслеживает все сопрограммы, которые он создает. Следовательно, если вы отменяете область действия, вы отменяете все сопрограммы, которые она создала

@ContributesViewModel
class SplashViewModel @Inject constructor(private val prefs: PrefStore) : BaseViewModel() {

    val onMoveToNext = ClassLiveData()

    init {
        scope.launch {
            val activity = if(prefs.isLoggedIn()) HomeActivity::class
            else OnBoardingActivity::class
            onMoveToNext.postValue(activity)
        }
    }

    ///fun saveDeviceID(id:String) = prefs.setDeviceID(id)
    //fun createErrorCodeHash() ={}

    fun getIsLoggedIn():Boolean = prefs.isLoggedIn()

    fun setSecondTimeLogin(boolean: Boolean) = prefs.setIsSecondTimeLogin(boolean)
}

Где

abstract class BaseViewModel: ViewModel() {

    private val job = Job()
    val scope = CoroutineScope(Dispatchers.IO + job)

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

}

где ClassLiveData

typealias ClassLiveData = MutableLiveData<KClass<*>>

И вызывали еев SplashActivity

viewModel.onMoveToNext.listen(this) {
    Handler().postDelayed({
         val intent = Intent(this, it.java)
        intent.putExtra("Role", "LOGIN")
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
        startActivity(intent)
    }, 2000)

1 Ответ

0 голосов
/ 25 октября 2019

Как правило, когда дело доходит до сохранения ссылки на context или других объектов, которые имеют жесткие ссылки на context (например, ContextWrapper, откуда берется SharedPrefferences), одинследует относиться к сопрограммам так же, как к классическим нитям.

Например, живая сопрограмма с Dispathers.IO потенциально может пропустить context точно так же, как классические thread, AsyncTasks и т. Д. Поэтому управление этимиссылки и их очистка являются обязанностью разработчиков.

Оглядываясь назад на ваш код, ваша база ViewModel работает с IO scope, что означает любой пустой конструктор luanch es, создающий дочерний элементсфера на том же Dispatcher, т.е. IO. Однако из-за вашего ViewModel.onCleared():

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

вы в значительной степени в безопасности.

Почему я говорю "в значительной степени"?

Потому что это зависит от того, как вы реализуете launch es. Помните, что только отмена job не обязательно означает, что соответствующая сопрограмма близка и все ссылки удалены. В некоторых реализациях требуется, чтобы вы непосредственно проверяли состояние своей работы внутри области и выполняли ручную очистку:

Например, если вы создаете цикл while внутри сопрограммы, job.cancel() не прерывает его , вам нужно break сделать это вручную.

Оглядываясь в последний раз на свой код, вы ничего не делаете внутри вашего launch, что требует ручной очистки. Тогда мы можем сказать, что ваш текущий код определенно не пропустит context.

...