可以与Coroutine kotlin一起使用sharedPrefrence

时间:2019-10-24 07:59:59

标签: android kotlin kotlin-coroutines android-viewmodel

我在sharedPreference中注入了ViewModel

  

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

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

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 :(得分:0)

作为一般经验法则,要保留对context或在context上具有硬引用的其他对象的引用(例如ContextWrapper,即{{1 }}来自),应该将协程与经典线程一样对待。

例如,与SharedPrefferencesDispathers.IO相同的方式,具有context 潜在地的实时协程可能泄漏thread,因此,管理这些引用并清理它们是开发人员的责任。

回顾代码,您的基础AsyncTasksViewModel范围内工作,这意味着任何空构造函数IO都在同一个{{1} },即luanch。但是,由于您的Dispatcher

IO

非常安全。

我为什么要说“差不多”?

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

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

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