Android Studio – 29 – Dependency Injection with Dagger

Dependency Injection (DI) is a software design pattern used to achieve Inversion of Control (IoC) in Android applications. DI involves supplying the dependencies that a class needs from external sources rather than creating them within the class itself. This promotes modularity, testability, and easier maintenance of your code. Dagger is a popular DI framework for Android that simplifies the process of dependency injection. In this guide, we will explore dependency injection with Dagger in Android Studio, its significance, and the steps to follow, along with code examples and commands for illustration.

The Significance of Dependency Injection

Dependency injection offers several benefits for Android app development:

  1. Modularity: With DI, components of your app are loosely coupled, making it easier to replace or modify individual parts without affecting the entire system.
  2. Testability: DI makes it easier to write unit tests for your classes because you can provide mock dependencies during testing.
  3. Reusability: By injecting dependencies, you can reuse components across different parts of your app, reducing code duplication.
  4. Maintainability: Code with fewer dependencies and clearer dependencies is generally easier to maintain.
  5. Readability: DI often leads to more readable and understandable code, as dependencies are explicitly defined.

Using Dagger for Dependency Injection

Dagger is a popular DI framework for Android that simplifies the process of injecting dependencies into your classes. Here are the steps to follow:

1. Add Dagger Dependencies:

To use Dagger in your Android Studio project, add the Dagger dependencies to your app’s build.gradle file:

dependencies {
    implementation 'com.google.dagger:dagger:2.x' // Replace '2.x' with the latest version
    annotationProcessor 'com.google.dagger:dagger-compiler:2.x' // Replace '2.x' with the latest version
}

Ensure that you use the latest version of Dagger available.

2. Create Dagger Components:

Dagger uses components to define the dependency injection graph. Components are interfaces or abstract classes annotated with @Component. They specify which classes can request dependencies. Here’s an example:

@Component
public interface AppComponent {
    void inject(MyActivity activity);
}

In this example, we’ve defined an AppComponent that can inject dependencies into a MyActivity class.

3. Provide Dependencies:

To provide dependencies, create a module. Modules are classes annotated with @Module that define how to create and provide instances of the dependencies. Here’s an example:

@Module
public class AppModule {
    @Provides
    public ApiService provideApiService() {
        return new ApiService();
    }
}

In this example, we’ve defined a module AppModule that provides an instance of ApiService.

4. Inject Dependencies:

In your Android component (e.g., an Activity or Fragment), use Dagger to inject the required dependencies. Here’s an example:

public class MyActivity extends AppCompatActivity {
    @Inject
    ApiService apiService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Initialize Dagger
        AppComponent appComponent = DaggerAppComponent.builder()
            .appModule(new AppModule())
            .build();
        appComponent.inject(this);

        // Now, you can use 'apiService' in this activity
    }
}

In this example, we’ve injected the apiService dependency into the MyActivity class.

5. Build the Dependency Graph:

To build the dependency graph and create Dagger components, use the Dagger generated code. You typically do this in your application’s onCreate method. Here’s an example:

public class MyApplication extends Application {
    private AppComponent appComponent;

    @Override
    public void onCreate() {
        super.onCreate();

        appComponent = DaggerAppComponent.builder()
            .appModule(new AppModule())
            .build();
    }

    public AppComponent getAppComponent() {
        return appComponent;
    }
}

In this example, we’ve built the appComponent and made it accessible through a getter method in the MyApplication class.

6. Use the Dependency Graph:

Now that you have a Dagger component and dependencies provided by modules, you can use them throughout your app. Dagger will take care of providing and injecting the dependencies when needed.

Example: Dependency Injection with Dagger

Let’s illustrate the process of dependency injection with Dagger with a simple example.

Suppose you have an ApiService class:

public class ApiService {
    public String fetchData() {
        // Fetch data from a remote API
        return "Data from the API";
    }
}

And a MyActivity class that needs to use ApiService:

public class MyActivity extends AppCompatActivity {
    @Inject
    ApiService apiService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Initialize Dagger
        AppComponent appComponent = DaggerAppComponent.builder()
            .appModule(new AppModule())
            .build();
        appComponent.inject(this);

        // Use 'apiService' to fetch data
        String data = apiService.fetchData();
        // Display 'data' in the UI or perform other operations
    }
}

In this example:

  • We have an ApiService class that simulates fetching data from a remote API.
  • The MyActivity class injects ApiService using Dagger.
  • We’ve created a Dagger component (AppComponent) and a module (AppModule) to provide and inject the ApiService dependency.

After setting up Dagger, it will automatically provide the apiService dependency to MyActivity.

Conclusion

Dependency injection with Dagger is a powerful technique for managing dependencies in Android app development. By following the steps outlined in this guide, you can enhance the modularity, testability, and maintainability of your Android app. Dagger simplifies the process of injecting dependencies, making your code more robust and easier to work with.