Repository: rakshakhegde/DaggerAndroidInjector Branch: master Commit: ee6f67968a7d Files: 26 Total size: 22.2 KB Directory structure: gitextract_tobp35st/ ├── .gitignore ├── README.MD ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── me/ │ │ └── rakshakhegde/ │ │ └── dagger_android_injector/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── me/ │ │ │ └── rakshakhegde/ │ │ │ └── dagger_android_injector/ │ │ │ ├── App.java │ │ │ ├── dependencies/ │ │ │ │ ├── AppComponent.java │ │ │ │ └── InjectorsModule.java │ │ │ └── screens/ │ │ │ └── main_screen/ │ │ │ ├── MainActivity.java │ │ │ ├── MainModule.java │ │ │ ├── MainView.java │ │ │ └── MainViewModel.java │ │ └── res/ │ │ ├── layout/ │ │ │ └── activity_main.xml │ │ └── values/ │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test/ │ └── java/ │ └── me/ │ └── rakshakhegde/ │ └── dagger_android_injector/ │ └── screens/ │ └── main_screen/ │ └── MainViewModelTest.java ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.iml .gradle /local.properties /.idea/ .DS_Store /build /captures .externalNativeBuild ================================================ FILE: README.MD ================================================ [![BuddyBuild Continuous Integration](https://dashboard.buddybuild.com/api/statusImage?appID=5902e07342b8090001523d74&branch=master&build=latest)](https://dashboard.buddybuild.com/apps/5902e07342b8090001523d74/build/latest?branch=master) # Dagger Android Injector ### [Kotlin branch here](https://github.com/rakshakhegde/DaggerAndroidInjector/tree/kotlin) **Update**: Latest Dagger 2.11 has provided some helper classes. Check out [**App.java**](https://github.com/rakshakhegde/DaggerAndroidInjector/blob/master/app/src/main/java/me/rakshakhegde/dagger_android_injector/App.java) for the updated simplified usage. [**Reddit discussion**](https://www.reddit.com/r/androiddev/comments/68jowo/dependency_injection_for_android_how_to_use/) Sample project to demonstrate how to use the new [**dagger-android**](https://google.github.io/dagger/android.html) module in latest Dagger [v2.11](https://github.com/google/dagger/releases). Along with [Proguard rules](https://github.com/rakshakhegde/DaggerAndroidInjector/blob/master/app/proguard-rules.pro#L27). Also shows [MVVM pattern](https://labs.ribot.co.uk/approaching-android-with-mvvm-8ceec02d5442) and [Unit Test](https://github.com/rakshakhegde/DaggerAndroidInjector/blob/master/app/src/test/java/me/rakshakhegde/dagger_android_injector/screens/main_screen/MainViewModelTest.java#L13) setup with [Mockito](https://github.com/rakshakhegde/DaggerAndroidInjector/blob/master/app/build.gradle#L44) on the side. ### Show some :heart: [![GitHub stars](https://img.shields.io/github/stars/rakshakhegde/DaggerAndroidInjector.svg?style=social&label=Star)](https://github.com/rakshakhegde/DaggerAndroidInjector) [![GitHub forks](https://img.shields.io/github/forks/rakshakhegde/DaggerAndroidInjector.svg?style=social&label=Fork)](https://github.com/rakshakhegde/DaggerAndroidInjector/fork) [![GitHub watchers](https://img.shields.io/github/watchers/rakshakhegde/DaggerAndroidInjector.svg?style=social&label=Watch)](https://github.com/rakshakhegde/DaggerAndroidInjector) [![GitHub followers](https://img.shields.io/github/followers/rakshakhegde.svg?style=social&label=Follow)](https://github.com/rakshakhegde) [![Twitter Follow](https://img.shields.io/twitter/follow/rakshakhegde.svg?style=social)](https://twitter.com/rakshakhegde) ## Motivation Right now you maybe getting the Application instance from Activity and injecting ("hydrating") instances based off of that. But the latest version of dagger basically decouples your Activity from knowing who your `Injector` is. So this sample project was built because I myself spent a bit of time getting **dagger-android** module setup at my company [Instavans](http://www.instavans.com/). There are things like getting all the correct library versions to work together. So here is a working starting point on how to use Dagger's `@ContributesAndroidInjector` which you can build upon. *(click on the images to go to the source)*

MainActivity Demo Injectors Module Demo

## License ```txt Copyright 2017 Rakshak R.Hegde Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ``` ================================================ FILE: app/.gitignore ================================================ /build ================================================ FILE: app/build.gradle ================================================ apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "me.rakshakhegde.dagger_android_injector" minSdkVersion 14 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } dataBinding.enabled = true } ext { daggerVersion = "2.11" jsr305Version = "3.0.1" } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support.constraint:constraint-layout:1.0.2' // Uncomment if you're not using support library and remove 'dagger-android-support' below // compile "com.google.dagger:dagger-android:$daggerVersion" compile "com.google.dagger:dagger-android-support:$daggerVersion" annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" annotationProcessor "com.google.dagger:dagger-android-processor:$daggerVersion" compile "com.google.code.findbugs:jsr305:$jsr305Version" testCompile 'junit:junit:4.12' testCompile "org.mockito:mockito-core:2.8.9" androidTestCompile "com.google.code.findbugs:jsr305:$jsr305Version" androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) } ================================================ FILE: app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # By default, the flags in this file are appended to flags specified # in /Users/rakshakhegde/Library/Android/sdk/tools/proguard/proguard-android.txt # You can edit the include path and order by changing the proguardFiles # directive in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # Add any project specific keep options here: # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile -dontwarn com.google.errorprone.annotations.* ================================================ FILE: app/src/androidTest/java/me/rakshakhegde/dagger_android_injector/ExampleInstrumentedTest.java ================================================ package me.rakshakhegde.dagger_android_injector; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; import static org.junit.Assert.*; /** * Instrumentation test, which will execute on an Android device. * * @see Testing documentation */ @RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest { @Test public void useAppContext() throws Exception { // Context of the app under test. Context appContext = InstrumentationRegistry.getTargetContext(); assertEquals("me.rakshakhegde.dagger_android_injector", appContext.getPackageName()); } } ================================================ FILE: app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: app/src/main/java/me/rakshakhegde/dagger_android_injector/App.java ================================================ package me.rakshakhegde.dagger_android_injector; import dagger.android.AndroidInjector; import dagger.android.DaggerApplication; import me.rakshakhegde.dagger_android_injector.dependencies.DaggerAppComponent; /** * Created by rakshakhegde on 26/04/17. */ public class App extends DaggerApplication { @Override protected AndroidInjector applicationInjector() { return DaggerAppComponent.builder().create(this); } } ================================================ FILE: app/src/main/java/me/rakshakhegde/dagger_android_injector/dependencies/AppComponent.java ================================================ package me.rakshakhegde.dagger_android_injector.dependencies; import javax.inject.Singleton; import dagger.Component; import dagger.android.AndroidInjector; import dagger.android.support.AndroidSupportInjectionModule; import me.rakshakhegde.dagger_android_injector.App; /** * Created by rakshakhegde on 26/04/17. */ @Singleton @Component(modules = { AndroidSupportInjectionModule.class, InjectorsModule.class }) public interface AppComponent extends AndroidInjector { @Component.Builder abstract class Builder extends AndroidInjector.Builder { } } ================================================ FILE: app/src/main/java/me/rakshakhegde/dagger_android_injector/dependencies/InjectorsModule.java ================================================ package me.rakshakhegde.dagger_android_injector.dependencies; import dagger.Module; import dagger.android.ContributesAndroidInjector; import me.rakshakhegde.dagger_android_injector.screens.main_screen.MainActivity; import me.rakshakhegde.dagger_android_injector.screens.main_screen.MainModule; /** * Created by rakshakhegde on 26/04/17. */ @Module abstract class InjectorsModule { @ContributesAndroidInjector(modules = {MainModule.class}) abstract MainActivity mainActivity(); // Add more ContributesAndroidInjector here... } ================================================ FILE: app/src/main/java/me/rakshakhegde/dagger_android_injector/screens/main_screen/MainActivity.java ================================================ package me.rakshakhegde.dagger_android_injector.screens.main_screen; import android.databinding.DataBindingUtil; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.Toast; import javax.inject.Inject; import dagger.android.AndroidInjection; import me.rakshakhegde.dagger_android_injector.R; import me.rakshakhegde.dagger_android_injector.databinding.ActivityMainBinding; public class MainActivity extends AppCompatActivity implements MainView { /** * MVVM pattern */ @Inject MainViewModel VM; @Override protected void onCreate(Bundle savedInstanceState) { /* Make sure you're injecting before onCreate. Order matters if using Fragments. On Activity restore, if injection is done after onCreate, app could crash if Fragments try to inject first. */ AndroidInjection.inject(this); super.onCreate(savedInstanceState); ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); binding.setVM(VM); } @Override public void showMessage(int message) { Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); } } ================================================ FILE: app/src/main/java/me/rakshakhegde/dagger_android_injector/screens/main_screen/MainModule.java ================================================ package me.rakshakhegde.dagger_android_injector.screens.main_screen; import dagger.Binds; import dagger.Module; import dagger.Provides; /** * Created by rakshakhegde on 26/04/17. */ @Module public abstract class MainModule { @Binds abstract MainView mainView(MainActivity act); @Provides static String providesUnusedData() { return "Unused Data"; } // Add more @Provides here } ================================================ FILE: app/src/main/java/me/rakshakhegde/dagger_android_injector/screens/main_screen/MainView.java ================================================ package me.rakshakhegde.dagger_android_injector.screens.main_screen; /** * Created by rakshakhegde on 26/04/17. */ public interface MainView { void showMessage(int message); } ================================================ FILE: app/src/main/java/me/rakshakhegde/dagger_android_injector/screens/main_screen/MainViewModel.java ================================================ package me.rakshakhegde.dagger_android_injector.screens.main_screen; import javax.inject.Inject; import me.rakshakhegde.dagger_android_injector.R; /** * Created by rakshakhegde on 26/04/17. */ public class MainViewModel { private MainView V; @Inject MainViewModel(MainView V) { this.V = V; } public void showBtnClicked() { V.showMessage(R.string.showing_toast); } } ================================================ FILE: app/src/main/res/layout/activity_main.xml ================================================