I try to store & get data using a datastore-preference alpha07, everything working fine, I got some memory leak issue in the datastore
What's the best practice to prevent memory leaks using Datastore?
here is my sample code:
// Preferences DataStore
implementation "androidx.datastore:datastore-preferences:1.0.0-alpha07"
// Leakcanary find memory leak
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.6'
UserManager.kt
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
class UserManager(val dataStore: DataStore<Preferences>) {
//Create some keys
companion object {
val USER_AGE_KEY = intPreferencesKey("USER_AGE")
val USER_FIRST_NAME_KEY = stringPreferencesKey("USER_FIRST_NAME")
val USER_LAST_NAME_KEY = stringPreferencesKey("USER_LAST_NAME")
val USER_GENDER_KEY = booleanPreferencesKey("USER_GENDER")
}
//Store user data
suspend fun storeUser(age: Int, fname: String, lname: String, isMale: Boolean) {
dataStore.edit {
it[USER_AGE_KEY] = age
it[USER_FIRST_NAME_KEY] = fname
it[USER_LAST_NAME_KEY] = lname
it[USER_GENDER_KEY] = isMale
}
}
//Create an age flow
val userAgeFlow: Flow<Int?> = dataStore.data.map {
it[USER_AGE_KEY]
}
//Create a fname flow
val userFirstNameFlow: Flow<String?> = dataStore.data.map {
it[USER_FIRST_NAME_KEY]
}
//Create a lname flow
val userLastNameFlow: Flow<String?> = dataStore.data.map {
it[USER_LAST_NAME_KEY]
}
//Create a gender flow
val userGenderFlow: Flow<Boolean?> = dataStore.data.map {
it[USER_GENDER_KEY]
}
}
User.kt
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStore
// At the top level of your kotlin file:
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "user_prefs")
SignInFragment.kt
//Get reference to our userManager class
var userManager = UserManager(requireContext().dataStore)
//Stores the values
lifecycleScope.launch {
userManager.storeUser(1, "android", "studio", true)
}
HomeFragment.kt
var userManager = UserManager(requireContext().dataStore)
userManager.userAgeFlow.asLiveData().observe(requireActivity(), {
if (it != null) {
age = it
//tv_age.text = it.toString()
}
})
Below solution not working I tried, still I am getting leaks even tried this solution, Observer should be bind with component's lifecycle in this case Fragment's lifecycle . Use viewLifeCycleOwner instead to bind the observer.
HomeFragment.kt
var userManager = UserManager(viewLifecycleOwner.dataStore)
userManager.userAgeFlow.asLiveData().observe(viewLifeCycleOwner, {
if (it != null) {
// age = it
// tv_age.text = it.toString()
}
})
Ref screenshot (again replicated)
from What's the best practice to prevent memory leaks using Datastore?
No comments:
Post a Comment