aster.cloud aster.cloud
  • /
  • Platforms
    • Public Cloud
    • On-Premise
    • Hybrid Cloud
    • Data
  • Architecture
    • Design
    • Solutions
    • Enterprise
  • Engineering
    • Automation
    • Software Engineering
    • Project Management
    • DevOps
  • Programming
    • Learning
  • Tools
  • About
  • /
  • Platforms
    • Public Cloud
    • On-Premise
    • Hybrid Cloud
    • Data
  • Architecture
    • Design
    • Solutions
    • Enterprise
  • Engineering
    • Automation
    • Software Engineering
    • Project Management
    • DevOps
  • Programming
    • Learning
  • Tools
  • About
aster.cloud aster.cloud
  • /
  • Platforms
    • Public Cloud
    • On-Premise
    • Hybrid Cloud
    • Data
  • Architecture
    • Design
    • Solutions
    • Enterprise
  • Engineering
    • Automation
    • Software Engineering
    • Project Management
    • DevOps
  • Programming
    • Learning
  • Tools
  • About
  • Programming

DataStore And Dependency Injection

  • aster.cloud
  • February 11, 2022
  • 4 minute read

In the following posts from our Jetpack DataStore series, we will cover several additional concepts to understand how DataStore interacts with other APIs, so that you’ll have everything at your disposal to use in a production environment. In this post specifically, we will be focusing on dependency injection with Hilt. We will be referring to the DataStore Preferences and Proto codelabs throughout this post for code samples.

Dependency injection with Hilt

In these codelabs, we interacted with our DataStore instances through the Preferences and Proto delegate construction once at the top level of a Kotlin file. We would then use the same instance throughout your application, as a singleton:


Partner with aster.cloud
for your next big idea.
Let us know here.



From our partners:

CITI.IO :: Business. Institutions. Society. Global Political Economy.
CYBERPOGO.COM :: For the Arts, Sciences, and Technology.
DADAHACKS.COM :: Parenting For The Rest Of Us.
ZEDISTA.COM :: Entertainment. Sports. Culture. Escape.
TAKUMAKU.COM :: For The Hearth And Home.
ASTER.CLOUD :: From The Cloud And Beyond.
LIWAIWAI.COM :: Intelligence, Inside and Outside.
GLOBALCLOUDPLATFORMS.COM :: For The World's Computing Needs.
FIREGULAMAN.COM :: For The Fire In The Belly Of The Coder.
ASTERCASTER.COM :: Supra Astra. Beyond The Stars.
BARTDAY.COM :: Prosperity For Everyone.

/* Copyright 2022 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 */

// Preferences DataStore
private val Context.dataStore by preferencesDataStore(name = USER_PREFERENCES_NAME)

// Proto DataStore
private val Context.userPreferencesStore by dataStore(
  fileName = DATA_STORE_FILE_NAME,
  serializer = UserPreferencesSerializer
)

We require a singleton because creating more than one instance of DataStore for one given file can break all DataStore functionality. However, in a production environment we would usually obtain the DataStore instance via dependency injection. So let’s take a look at how DataStore works with Hilt, a dependency injection library that will help us reduce the boilerplate of doing manual dependency management. If you’re not familiar with Hilt, we encourage you to first go through the Using Hilt in your Android app codelab to learn the basic concepts such as Components, Modules and others.

Hilt setup

First, make sure you’ve added all the necessary setup steps to enable Hilt:

/* Copyright 2022 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 */
   
// Root build.gradle    
dependencies {
  classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
}

// Module build.gradle:
plugins {
  id 'kotlin-kapt'
  id 'dagger.hilt.android.plugin'
}

dependencies {
  implementation "com.google.dagger:hilt-android:$hilt_version"
  kapt "com.google.dagger:hilt-compiler:$hilt_version"
}

All apps that use Hilt must contain an Application class that is annotated with @HiltAndroidApp to trigger Hilt’s code generation, including a base class for your application that serves as the application-level dependency container. In our case, we will create a simple TasksApp and add it to our AndroidManifest.xml:

/* Copyright 2022 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 */

@HiltAndroidApp
class TasksApp : Application()

// AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.codelab.android.datastore">

    <application
        android:name=".TasksApp"/>
</manifest>

Injecting Preferences DataStore

To obtain a Preferences DataStore instance through injection, we need to tell Hilt how to properly create it. We use the PreferenceDataStoreFactory and add it to a Hilt module:

Read More  PyCon 2019 | Making Music with Python, SuperCollider and FoxDot
/* Copyright 2022 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 */
   
private const val USER_PREFERENCES = "user_preferences"

@InstallIn(SingletonComponent::class)
@Module
object DataStoreModule {

    @Singleton
    @Provides
    fun providePreferencesDataStore(@ApplicationContext appContext: Context): DataStore<Preferences> {
        return PreferenceDataStoreFactory.create(
            corruptionHandler = ReplaceFileCorruptionHandler(
                produceNewData = { emptyPreferences() }
            ),
            migrations = listOf(SharedPreferencesMigration(appContext,USER_PREFERENCES)),
            scope = CoroutineScope(Dispatchers.IO + SupervisorJob()),
            produceFile = { appContext.preferencesDataStoreFile(USER_PREFERENCES) }
        )
    }
}

We’ve mentioned these parameters previously in the series, but let’s quickly recap:

  • corruptionHandler (optional) — invoked if a CorruptionException is thrown by the serializer when the data cannot be de-serialized which instructs DataStore how to replace the corrupted data
  • migrations (optional) — a list of DataMigration for moving previous data into DataStore
  • scope (optional) — the scope in which IO operations and transform functions will execute; in this case, we’re reusing the same scope as the DataStore API default one
  • produceFile — generates the File object for Preferences DataStore based on the provided Context and name, stored in this.applicationContext.filesDir + datastore/ subdirectory

Now that we have a module to instruct Hilt on how to create our DataStore, we need to make a few more adjustments to be able to build successfully.

Hilt can provide dependencies to other Android classes that have the @AndroidEntryPoint annotation, along with @HiltAndroidApp for Application and @HiltViewModel for ViewModel classes. If you annotate an Android class with @AndroidEntryPoint, then you also must annotate other Android classes that depend on it. For example, if you annotate a Fragment, then you must also annotate any activities where you use that Fragment.

That means we need to add the following:

/* Copyright 2022 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 */
   
@AndroidEntryPoint
class TasksActivity : AppCompatActivity()

@HiltViewModel
class TasksViewModel

In this sample, we don’t have any other complex injections, such as custom builders, factories, or interface implementations. So we can rely on Hilt and constructor injection for any other dependencies that we need to pass. We will use the @Inject annotation in the constructor of a class to instruct Hilt how to provide its instances:

Read More  How Different Programming Languages Read And Write Data
/* Copyright 2022 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 */
   
@HiltViewModel
class TasksViewModel @Inject constructor(
    repository: TasksRepository,
    private val userPreferencesRepository: UserPreferencesRepository
) : ViewModel() {

class UserPreferencesRepository @Inject constructor(
    private val dataStore: DataStore<Preferences>
)

class TasksRepository @Inject constructor()

Finally, let’s completely remove the preferencesDataStore delegate from the top of our TasksActivity as we don’t need it anymore. We will also change how our viewModel is provided in TaskActivity onCreate, as its dependencies will now be injected:

/* Copyright 2022 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 */
   
viewModel = ViewModelProvider(this).get(TasksViewModel::class.java)

Injecting Proto DataStore

Proto DataStore would follow a very similar pattern — you’d additionally need to provide a UserPreferencesSerializer and a precise instruction on how to migrate from SharedPreferences, which we’ve covered in more detail in the Proto DataStore post:

/* Copyright 2022 Google LLC.	
   SPDX-License-Identifier: Apache-2.0 */
   
private const val USER_PREFERENCES_NAME = "user_preferences"
private const val DATA_STORE_FILE_NAME = "user_prefs.pb"

@InstallIn(SingletonComponent::class)
@Module
object DataStoreModule {

    @Singleton
    @Provides
    fun provideProtoDataStore(@ApplicationContext appContext: Context): DataStore<UserPreferences> {
        return DataStoreFactory.create(
            serializer = UserPreferencesSerializer,
            produceFile = { appContext.dataStoreFile(DATA_STORE_FILE_NAME) },
            corruptionHandler = null,
            migrations = listOf(
                SharedPreferencesMigration(
                    appContext,
                    USER_PREFERENCES_NAME
                )
            scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
        )
    }
}

That’s it! Now you’ll be able to run the app and verify that all the dependencies are now being injected properly.

To be continued

We’ve covered steps on how to inject DataStore with Hilt for better dependency management, setting up Hilt, using the PreferenceDataStoreFactory in our DataStoreModule to instruct Hilt on how to provide our DataStore instance correctly, and finally, providing it to classes that require it.

Join us for the next post of our series where we will be looking into how to use Data Store with Kotlin Serialization.

Read More  Jetpack Compose: The Alpha Release!

By Simona Stojanovic
Source Medium


For enquiries, product placements, sponsorships, and collaborations, connect with us at [email protected]. We'd love to hear from you!

Our humans need coffee too! Your support is highly appreciated, thank you!

aster.cloud

Related Topics
  • DataStore
  • Jetpack
  • Kotlin
You May Also Like
View Post
  • Architecture
  • Data
  • Engineering
  • People
  • Programming
  • Software Engineering
  • Technology
  • Work & Jobs

Predictions: Top 25 Careers Likely In High Demand In The Future

  • June 6, 2023
View Post
  • Programming
  • Software Engineering
  • Technology

Build a Python App to Alert You When Asteroids Are Close to Earth

  • May 22, 2023
View Post
  • Programming

Illuminating Interactions: Visual State In Jetpack Compose

  • May 20, 2023
View Post
  • Computing
  • Data
  • Programming
  • Software
  • Software Engineering

The Top 10 Data Interchange Or Data Exchange Format Used Today

  • May 11, 2023
View Post
  • Architecture
  • Programming
  • Public Cloud

From Receipts To Riches: Save Money W/ Google Cloud & Supermarket Bills – Part 1

  • May 8, 2023
View Post
  • Programming
  • Public Cloud

3 New Ways To Authorize Users To Your Private Workloads On Cloud Run

  • May 4, 2023
View Post
  • Programming
  • Public Cloud

Buffer HTTP Requests With Cloud Tasks

  • May 4, 2023
View Post
  • Programming
  • Public Cloud
  • Software
  • Software Engineering

Learn About Google Cloud’s Updated Renderer For The Maps SDK For Android

  • May 4, 2023

Stay Connected!
LATEST
  • college-of-cardinals-2025 1
    The Definitive Who’s Who of the 2025 Papal Conclave
    • May 7, 2025
  • conclave-poster-black-smoke 2
    The World Is Revalidating Itself
    • May 6, 2025
  • oracle-ibm 3
    IBM and Oracle Expand Partnership to Advance Agentic AI and Hybrid Cloud
    • May 6, 2025
  • 4
    Conclave: How A New Pope Is Chosen
    • April 25, 2025
  • Getting things done makes her feel amazing 5
    Nurturing Minds in the Digital Revolution
    • April 25, 2025
  • 6
    AI is automating our jobs – but values need to change if we are to be liberated by it
    • April 17, 2025
  • 7
    Canonical Releases Ubuntu 25.04 Plucky Puffin
    • April 17, 2025
  • 8
    United States Army Enterprise Cloud Management Agency Expands its Oracle Defense Cloud Services
    • April 15, 2025
  • 9
    Tokyo Electron and IBM Renew Collaboration for Advanced Semiconductor Technology
    • April 2, 2025
  • 10
    IBM Accelerates Momentum in the as a Service Space with Growing Portfolio of Tools Simplifying Infrastructure Management
    • March 27, 2025
about
Hello World!

We are aster.cloud. We’re created by programmers for programmers.

Our site aims to provide guides, programming tips, reviews, and interesting materials for tech people and those who want to learn in general.

We would like to hear from you.

If you have any feedback, enquiries, or sponsorship request, kindly reach out to us at:

[email protected]
Most Popular
  • 1
    Tariffs, Trump, and Other Things That Start With T – They’re Not The Problem, It’s How We Use Them
    • March 25, 2025
  • 2
    IBM contributes key open-source projects to Linux Foundation to advance AI community participation
    • March 22, 2025
  • 3
    Co-op mode: New partners driving the future of gaming with AI
    • March 22, 2025
  • 4
    Mitsubishi Motors Canada Launches AI-Powered “Intelligent Companion” to Transform the 2025 Outlander Buying Experience
    • March 10, 2025
  • PiPiPi 5
    The Unexpected Pi-Fect Deals This March 14
    • March 13, 2025
  • /
  • Technology
  • Tools
  • About
  • Contact Us

Input your search keywords and press Enter.