可以与Coroutine Kotlin一起使用sharedPrefrence吗 [英] Is it ok to use sharedPrefrence with Coroutine kotlin

查看:95
本文介绍了可以与Coroutine Kotlin一起使用sharedPrefrence吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在ViewModel中注入了sharedPreference.

我可以在嵌入Coroutine范围时使用android特定资源吗?当ViewModel失去范围时,该范围会自动挂起.

Can I use android specific resource's while embedding Coroutine scope which automatically suspended when ViewModel loses scope.

我的意思是,如果我们添加一个viewModel启动范围,可以在ViewModel中使用Preferredende

I mean is it ok to use preferende in ViewModel if we add a viewModel launch scope

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

where ClassLiveData

typealias ClassLiveData = MutableLiveData<KClass<*>>

并在SplashActivity中调用它

And called it in 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)

推荐答案

作为一般经验法则,要保留对context或在context上具有硬引用的其他对象的引用(例如,,这是SharedPrefferences的来源),应将协程与经典线程一样对待.

As a general rule of thumb, when it comes to keeping a reference to context or other objects that have hard references on context (e.g. ContextWrapper, which is where SharedPrefferences are coming from), one should treat coroutines the same as classic threads.

例如,带有Dispathers.IO 潜在的实时协程可能以与经典threadAsyncTasks等相同的方式泄漏context.因此,请管理这些引用和清理它们是开发人员的责任.

For example, a live coroutine with Dispathers.IO potentially can leak the context in the same way as a classic thread, AsyncTasks, etc. Therefore, managing these references and cleaning them up is the developers' responsibility.

回头看一下代码,您的基础ViewModelIO范围内工作,这意味着任何空构造器luanch es都在同一Dispatcher上创建子范围,即IO.但是由于您的ViewModel.onCleared():

Looking back at your code, your base ViewModel is working on IO scope, which means any empty-constructor luanches, create a child scope on the same Dispatcher, i.e IO. However because of your ViewModel.onCleared():

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

相当是安全的.

我为什么要说差不多"?

Why am I saying "pretty much"?

因为这取决于您实现launch es的方式.请记住,仅取消job并不一定意味着相应的协程已关闭并且所有引用都已删除.某些实现需要您直接在范围内检查作业状态并进行手动清理:

Because it depends on how you implement your launches. Remember that only canceling a job doesn't necessarily mean that the corresponding coroutine is close and every reference is removed. Certain implementations need you directly check the state of your job inside the scope and do manual cleanups:

例如,如果在协程内部创建一个while循环,job.cancel() 不会破坏,则需要手动break.

For instance, if you create a while loop inside a coroutine, job.cancel() does not break it, you need to break it manually.

最后一次回顾您的代码,您没有在launch内部执行任何需要手动清理的操作.然后,可以说您当前的代码肯定不会泄漏context.

Looking back one last time at your code, you are not doing anything inside your launch that requires manual cleanups. Then, we can say your current code certainly won't leak the context.

这篇关于可以与Coroutine Kotlin一起使用sharedPrefrence吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆