Android

Android TutorialAdding a FuseView to an Android ProjectAndroid 9-Patch ImagesAndroid Accessing SQLite databases using the ContentValues classAndroid Accounts and AccountManagerAndroid ACRAAndroid ActivityAndroid Activity RecognitionAndroid adb (Android Debug Bridge)Android adb shellAndroid AdMobAndroid AIDLAndroid AlarmManagerAndroid Android-x86 in VirtualBoxAndroid Animated AlertDialog BoxAndroid AnimatorsAndroid Annotation ProcessorAndroid Architecture ComponentsAndroid AsyncTaskAndroid AudioManagerAndroid AudioTrackAndroid AuthenticatorAndroid AutoCompleteTextViewAndroid Autosizing TextViewsAndroid Barcode and QR code readingAndroid Bitmap CacheAndroid Bluetooth and Bluetooth LE APIAndroid Bluetooth Low EnergyAndroid Bottom SheetsAndroid BottomNavigationViewAndroid BroadcastReceiverAndroid Building Backwards Compatible AppsAndroid ButterKnifeAndroid ButtonAndroid Callback URLAndroid Camera 2 APIAndroid Camera and GalleryAndroid Canvas drawing using SurfaceViewAndroid Capturing ScreenshotsAndroid CardViewAndroid Check Data ConnectionAndroid Check Internet ConnectivityAndroid CleverTapAndroid ColorsAndroid ConstraintLayoutAndroid ConstraintSetAndroid ContentProviderAndroid ContextAndroid CoordinatorLayout and BehaviorsAndroid Count Down TimerAndroid Crash Reporting ToolsAndroid Create Singleton Class for Toast MessageAndroid Creating Custom ViewsAndroid Creating Overlay (always-on-top) WindowsAndroid Creating Splash screenAndroid Custom FontsAndroid Dagger 2Android Data Binding LibraryAndroid Data Encryption/DecryptionAndroid Data Synchronization with Sync AdapterAndroid Date and Time PickersAndroid DayNight Theme (AppCompat v23.2 / API 14+)Android Define step value (increment) for custom RangeSeekBarAndroid Design PatternsAndroid Device Display MetricsAndroid DialogAndroid Displaying Google AdsAndroid Doze ModeAndroid DrawablesAndroid EditTextAndroid Email ValidationAndroid EmulatorAndroid Enhancing Alert DialogsAndroid ExceptionsAndroid ExoPlayerAndroid FastjsonAndroid fastlaneAndroid FileProviderAndroid FirebaseAndroid Firebase App IndexingAndroid Firebase Cloud MessagingAndroid Firebase Crash ReportingAndroid Firebase Realtime DataBaseAndroid FloatingActionButtonAndroid Formatting phone numbers with pattern.Android Formatting StringsAndroid FragmentsAndroid FrescoAndroid game developmentAndroid Gesture Detection



Android Dagger 2

From WikiOD

Syntax[edit | edit source]

  • @Module
  • @Component(dependencies={OtherComponent.class}, modules={ModuleA.class, ModuleB.class})
  • DaggerMyComponent.create()
  • DaggerMyComponent.builder().myModule(newMyModule()).create()

Remarks[edit | edit source]

Not to confuse with dagger by square, the predecessor to dagger 2.

Component setup for Application and Activity injection[edit | edit source]

A basic AppComponent that depends on a single AppModule to provide application-wide singleton objects.

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {

    void inject(App app);

    Context provideContext();

    Gson provideGson();
}

A module to use together with the AppComponent which will provide its singleton objects, e.g. an instance of Gson to reuse throughout the whole application.

@Module
public class AppModule {

    private final Application mApplication;

    public AppModule(Application application) {
        mApplication = application;
    }

    @Singleton
    @Provides
    Gson provideGson() {
        return new Gson();
    }

    @Singleton
    @Provides
    Context provideContext() {
        return mApplication;
    }
}

A subclassed application to setup dagger and the singleton component.

public class App extends Application {

    @Inject
    AppComponent mAppComponent;

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

        DaggerAppComponent.builder().appModule(new AppModule(this)).build().inject(this);
    }

    public AppComponent getAppComponent() {
        return mAppComponent;
    }
}

Now an activity scoped component that depends on the AppComponent to gain access to the singleton objects.

@ActivityScope
@Component(dependencies = AppComponent.class, modules = ActivityModule.class)
public interface MainActivityComponent {

    void inject(MainActivity activity);
}

And a reusable ActivityModule that will provide basic dependencies, like a FragmentManager

@Module
public class ActivityModule {

    private final AppCompatActivity mActivity;

    public ActivityModule(AppCompatActivity activity) {
        mActivity = activity;
    }

    @ActivityScope
    public AppCompatActivity provideActivity() {
        return mActivity;
    }

    @ActivityScope
    public FragmentManager provideFragmentManager(AppCompatActivity activity) {
        return activity.getSupportFragmentManager();
    }
}

Putting everything together we're set up and can inject our activity and be sure to use the same Gson throughout out app!

public class MainActivity extends AppCompatActivity {

    @Inject
    Gson mGson;

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

        DaggerMainActivityComponent.builder()
                .appComponent(((App)getApplication()).getAppComponent())
                .activityModule(new ActivityModule(this))
                .build().inject(this);
    }
}

Custom Scopes[edit | edit source]

@Scope
@Documented
@Retention(RUNTIME)
public @interface ActivityScope {
}

Scopes are just annotations and you can create your own ones where needed.

Constructor Injection[edit | edit source]

Classes without dependencies can easily be created by dagger.

public class Engine {

    @Inject // <-- Annotate your constructor.
    public Engine() {
    }
}

This class can be provided by any component. It has no dependencies itself and is not scoped. There is no further code necessary.


Dependencies are declared as parameters in the constructor. Dagger will call the constructor and supply the dependencies, as long as those dependencies can be provided.

public class Car {

    private Engine engine;

    @Inject
    public Car(Engine engine) {
        this.engine = engine;
    }
}

This class can be provided by every component iff this component can also provide all of its dependencies—Engine in this case. Since Engine can also be constructor injected, any component can provide a Car.

You can use constructor injection whenever all of the dependencies can be provided by the component. A component can provide a dependency, if

  • it can create it by using constructor injection
  • a module of the component can provide it
  • it can be provided by the parent component (if it is a @Subcomponent)
  • it can use an object exposed by a component it depends on (component dependencies)

Using @Subcomponent instead of @Component(dependencies={...})[edit | edit source]

@Singleton
@Component(modules = AppModule.class)
public interface AppComponent {
    void inject(App app);

    Context provideContext();
    Gson provideGson();

    MainActivityComponent mainActivityComponent(ActivityModule activityModule);
}

@ActivityScope
@Subcomponent(modules = ActivityModule.class)
public interface MainActivityComponent {
    void inject(MainActivity activity);
}

public class MainActivity extends AppCompatActivity {

    @Inject
    Gson mGson;

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

        ((App)getApplication()).getAppComponent()
                .mainActivityComponent(new ActivityModule(this)).inject(this);
    }
}

How to add Dagger 2 in build.gradle[edit | edit source]

Since the release of Gradle 2.2, the use of the android-apt plugin is no longer used. The following method of setting up Dagger 2 should be used. For older version of Gradle, use the previous method shown below.

For Gradle >= 2.2

dependencies {
    // apt command comes from the android-apt plugin
    annotationProcessor 'com.google.dagger:dagger-compiler:2.8'
    compile 'com.google.dagger:dagger:2.8'
    provided 'javax.annotation:jsr250-api:1.0'
}

For Gradle < 2.2

To use Dagger 2 it's necessary to add android-apt plugin, add this to the root build.gradle:

buildscript {
    dependencies {
        classpath 'com.android.tools.build:gradle:2.1.0'
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
    }
}

Then the application module's build.gradle should contain:

apply plugin: 'com.android.application'
apply plugin: 'com.neenbedankt.android-apt'

android {
    …
}

final DAGGER_VERSION = '2.0.2'
dependencies {
    …

    compile "com.google.dagger:dagger:${DAGGER_VERSION}"
    apt "com.google.dagger:dagger-compiler:${DAGGER_VERSION}"
}

Reference: https://github.com/codepath/android_guides/wiki/Dependency-Injection-with-Dagger-2

Creating a component from multiple modules[edit | edit source]

Dagger 2 supports creating a component from multiple modules. You can create your component this way:

@Singleton
@Component(modules = {GeneralPurposeModule.class, SpecificModule.class})
public interface MyMultipleModuleComponent {
    void inject(MyFragment myFragment);
    void inject(MyService myService);
    void inject(MyController myController);
    void inject(MyActivity myActivity);
}

The two references modules GeneralPurposeModule and SpecificModule can then be implemented as follows:

GeneralPurposeModule.java

@Module
public class GeneralPurposeModule {
    @Provides
    @Singleton
    public Retrofit getRetrofit(PropertiesReader propertiesReader, RetrofitHeaderInterceptor headerInterceptor){
        // Logic here...
        return retrofit;
    }

    @Provides
    @Singleton
    public PropertiesReader getPropertiesReader(){
        return new PropertiesReader();
    }

    @Provides
    @Singleton
    public RetrofitHeaderInterceptor getRetrofitHeaderInterceptor(){
         return new RetrofitHeaderInterceptor();
    }
}

SpecificModule.java

@Singleton
@Module
public class SpecificModule {
    @Provides @Singleton
    public RetrofitController getRetrofitController(Retrofit retrofit){
        RetrofitController retrofitController = new RetrofitController();
        retrofitController.setRetrofit(retrofit);
        return retrofitController;
    }

    @Provides @Singleton
    public MyService getMyService(RetrofitController retrofitController){
        MyService myService = new MyService();
        myService.setRetrofitController(retrofitController);
        return myService;
    }
}

During the dependency injection phase, the component will take objects from both modules according to the needs.

This approach is very useful in terms of modularity. In the example, there is a general purpose module used to instantiate components such as the Retrofit object (used to handle the network communication) and a PropertiesReader (in charge of handling configuration files). There is also a specific module that handles the instantiation of specific controllers and service classes in relation to that specific application component.

Credit:Stack_Overflow_Documentation