Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The best way to wrap sharedPreference object in hilt

I have a sharedPreference object, and I want to make it as dependency inject component through the project.

// sharedPreference object
private const val PREF_TAG = "tag"
object MyPreference {
    fun getStoredTag(context: Context): String {
        val prefs = PreferenceManager.getDefaultSharedPreferences(context)
        return prefs.getString(PREF_TAG, "")!!
    }
    fun setStoredTag(context: Context, query: String) {
        PreferenceManager.getDefaultSharedPreferences(context)
            .edit()
            .putString(PREF_TAG, query)
            .apply()
    }
}

// How to correctly inject the sharedPreference?
// create a module?
@Module
@InstallIn(SingletonComponent::class)
object PreferenceModule {
    @Provides
    @Singleton
    fun provideSharedPreference(): SharedPreferences {
        return MyPreference()
    }
}
// or directly inject in viewModel
class LoginViewModel @ViewModelInject constructor(
    application: Application,
    myPreference: MyPreference
) : AndroidViewModel(application) {
    ...
}
// or another way?
like image 828
ccd Avatar asked Aug 29 '20 03:08

ccd


2 Answers

with Hilt 2.38.1:

SharedPreferencesModule.kt

@Module
@InstallIn(SingletonComponent::class)
class SharedPreferencesModule {

    @Singleton
    @Provides
    fun provideSharedPreference(@ApplicationContext context: Context): SharedPreferences {
        return context.getSharedPreferences("preferences_name", Context.MODE_PRIVATE)
    }
}

CustomViewModel.kt

@HiltViewModel
class CustomViewModel @Inject constructor(
    private val sharedPreferences: SharedPreferences
):ViewModel() {

    fun customFunction() {
        sharedPreferences.edit().putString("firstStoredString", "this is the content").apply()

        val firstStoredString = sharedPreferences.getString("firstStoredString", "")
    }
    ...
like image 126
ivoroto Avatar answered Nov 15 '22 21:11

ivoroto


This is a bit of an opinion-based answer, but at least I will give you a direction to follow.


You'd usually maintain an instance of SharedPreferences within your wrapper class. So...

  1. Use a regular class instead of an object declaration
  2. Since you want to have a Hilt setup, you can directly use hilt annotations for the class, directly injecting Context into the constructor
@Singleton
class MyPreference @Inject constructor(@ApplicationContext context : Context){
    val prefs = PreferenceManager.getDefaultSharedPreferences(context)

    fun getStoredTag(): String {
        return prefs.getString(PREF_TAG, "")!!
    }
    fun setStoredTag(query: String) {
        prefs.edit().putString(PREF_TAG, query).apply()
    }
}
  1. Then you don't need a Module, you can simply use the @ViewModelInject
class LoginViewModel @ViewModelInject constructor(
    application: Application,
    myPreference: MyPreference
) : AndroidViewModel(application) {
    ...
}
like image 35
Bartek Lipinski Avatar answered Nov 15 '22 19:11

Bartek Lipinski