Skip to content
This repository was archived by the owner on Aug 22, 2024. It is now read-only.

Commit 2deaa6f

Browse files
authored
Merge pull request #11 from amardeshbd/feature/6_setup_dagger_di
Feature/6 setup dagger di
2 parents 41c8410 + 082af8c commit 2deaa6f

File tree

13 files changed

+335
-8
lines changed

13 files changed

+335
-8
lines changed

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@
186186
same "printed page" as the copyright notice for easier
187187
identification within third-party archives.
188188

189-
Copyright [yyyy] [name of copyright owner]
189+
Copyright 2018 Hossain Khan
190190

191191
Licensed under the Apache License, Version 2.0 (the "License");
192192
you may not use this file except in compliance with the License.

app/build.gradle

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@ apply plugin: 'kotlin-android'
44

55
apply plugin: 'kotlin-android-extensions'
66

7+
// https://kotlinlang.org/docs/reference/kapt.html
8+
apply plugin: 'kotlin-kapt'
9+
710
android {
8-
compileSdkVersion rootProject.ext.targetSdkVersion
11+
compileSdkVersion rootProject.ext.androidCompileSdkVersion
912
defaultConfig {
1013
applicationId "com.hossainkhan.android.demo"
11-
minSdkVersion rootProject.ext.minSdkVersion
12-
targetSdkVersion rootProject.ext.targetSdkVersion
14+
minSdkVersion rootProject.ext.androidMinSdkVersion
15+
targetSdkVersion rootProject.ext.androidTargetSdkVersion
1316
versionCode 1
1417
versionName "1.0-constraint-layout-demo"
1518
versionNameSuffix "-${gitSha()}"
@@ -30,6 +33,10 @@ android {
3033
sourceCompatibility rootProject.ext.javaSourceCompatibilityVersion
3134
targetCompatibility rootProject.ext.javaTargetCompatibilityVersion
3235
}
36+
37+
testOptions {
38+
unitTests.returnDefaultValues = true
39+
}
3340
}
3441

3542
dependencies {
@@ -47,12 +54,24 @@ dependencies {
4754
// https://developer.android.com/topic/libraries/architecture/adding-components
4855
implementation "android.arch.lifecycle:extensions:$rootProject.archComponentVersion"
4956

57+
// ========================================================
5058
// 3rd party libraries
59+
// ========================================================
5160
debugImplementation "com.squareup.leakcanary:leakcanary-android:$rootProject.leakcanaryLibraryVersion"
5261
releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$rootProject.leakcanaryLibraryVersion"
5362

5463
implementation "com.jakewharton.timber:timber:$rootProject.timberLibraryVersion"
5564

65+
// Dagger
66+
// https://google.github.io/dagger/
67+
implementation "com.google.dagger:dagger:$rootProject.daggerVersion"
68+
kapt "com.google.dagger:dagger-compiler:$rootProject.daggerVersion"
69+
implementation "com.google.dagger:dagger-android:$rootProject.daggerVersion"
70+
// Include if you use the support libraries (eg. Support Activity, Fragment)
71+
//implementation "com.google.dagger:dagger-android-support:$rootProject.daggerVersion"
72+
kapt "com.google.dagger:dagger-android-processor:$rootProject.daggerVersion"
73+
74+
5675
// ----------------------------------------------------------------
5776
// Android Unit and Instrumentation test
5877
// ----------------------------------------------------------------

app/src/main/java/com/hossainkhan/android/demo/MainActivity.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,21 @@ package com.hossainkhan.android.demo
22

33
import android.support.v7.app.AppCompatActivity
44
import android.os.Bundle
5+
import com.hossainkhan.android.demo.data.AppDataStore
6+
import dagger.android.AndroidInjection
7+
import timber.log.Timber
8+
import javax.inject.Inject
59

610
class MainActivity : AppCompatActivity() {
11+
@Inject
12+
lateinit var appDataStore: AppDataStore
713

814
override fun onCreate(savedInstanceState: Bundle?) {
15+
AndroidInjection.inject(this)
916
super.onCreate(savedInstanceState)
1017
setContentView(R.layout.activity_main)
18+
19+
Timber.d("Got data: ${appDataStore.isFirstTime()}")
20+
appDataStore.updateFirstTimeUser(false)
1121
}
1222
}

app/src/main/java/com/hossainkhan/android/demo/base/DemoApplication.kt

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,36 @@
1+
/*
2+
* Copyright (c) 2018 Hossain Khan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package com.hossainkhan.android.demo.base
218

19+
import android.app.Activity
320
import android.app.Application
421
import com.hossainkhan.android.demo.BuildConfig
22+
import com.hossainkhan.android.demo.dagger.DaggerDemoApplicationComponent
523
import com.squareup.leakcanary.LeakCanary
24+
import dagger.android.AndroidInjector
25+
import dagger.android.DispatchingAndroidInjector
26+
import dagger.android.HasActivityInjector
627
import timber.log.Timber
28+
import javax.inject.Inject
729

830

9-
class DemoApplication : Application() {
31+
class DemoApplication : Application(), HasActivityInjector {
32+
@Inject
33+
lateinit var dispatchingAndroidInjector: DispatchingAndroidInjector<Activity>
1034

1135
override fun onCreate() {
1236
super.onCreate()
@@ -17,8 +41,19 @@ class DemoApplication : Application() {
1741
}
1842
LeakCanary.install(this)
1943

44+
// Prepares dagger
45+
DaggerDemoApplicationComponent.builder()
46+
.application(this)
47+
.build()
48+
.inject(this)
49+
2050
if (BuildConfig.DEBUG) {
2151
Timber.plant(Timber.DebugTree())
2252
}
2353
}
54+
55+
override fun activityInjector(): AndroidInjector<Activity> {
56+
return dispatchingAndroidInjector
57+
}
58+
2459
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2018 Hossain Khan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.hossainkhan.android.demo.dagger
18+
19+
import dagger.Module
20+
21+
/**
22+
* We want Dagger.Android to create a Subcomponent which has a parent Component of whichever
23+
* module ActivityBindingModule is on, in our case that will be [DemoApplicationComponent].
24+
*
25+
* The beautiful part about this setup is that you never need to tell [DemoApplicationComponent]
26+
* that it is going to have all these subcomponents nor do you need to tell these subcomponents
27+
* that [DemoApplicationComponent] exists.
28+
*
29+
* We are also telling Dagger.Android that this generated SubComponent needs to include
30+
* the specified modules and be aware of a scope annotation @ActivityScoped
31+
* When Dagger.Android annotation processor runs it will create subcomponents for us.
32+
*/
33+
@Module
34+
public abstract class ActivityBindingModule {
35+
/*
36+
* https://google.github.io/dagger/android.html
37+
* Pro-tip: If your subcomponent and its builder have no other methods or supertypes than
38+
* the ones mentioned in step #2, you can use @ContributesAndroidInjector to generate them for you.
39+
*
40+
* Instead of steps 2 and 3, add an abstract module method that returns your activity,
41+
* annotate it with @ContributesAndroidInjector, and specify the modules you want to install
42+
* into the subcomponent. If the subcomponent needs scopes, apply the scope annotations to
43+
* the method as well.
44+
*/
45+
// Example
46+
//@ActivityScoped
47+
//@ContributesAndroidInjector(modules = arrayOf(ModuleNameWhichHasActivityInjection::class))
48+
//abstract fun someActivity(): SomeActivity
49+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2018 Hossain Khan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.hossainkhan.android.demo.dagger
18+
19+
import android.app.Application
20+
import android.content.Context
21+
import dagger.Binds
22+
import dagger.Module
23+
24+
/**
25+
* This is a Dagger module. We use this to bind our Application class as a Context in
26+
* the [DemoApplicationComponent] By using Dagger Android we do not need to pass
27+
* our Application instance to any module, we simply need to expose our Application as Context.
28+
* One of the advantages of Dagger.Android is that your
29+
* Application & Activities are provided into your graph for you.
30+
*
31+
* @see DemoApplicationComponent
32+
*/
33+
@Module
34+
abstract class ApplicationModule {
35+
//expose Application as an injectable context
36+
@Binds
37+
internal abstract fun bindContext(application: Application): Context
38+
39+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2018 Hossain Khan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.hossainkhan.android.demo.dagger
18+
19+
import android.content.Context
20+
import android.content.SharedPreferences
21+
import dagger.Module
22+
import dagger.Provides
23+
24+
@Module
25+
class DataStoreModule {
26+
@Provides
27+
internal fun provideSharedPreferences(context: Context): SharedPreferences {
28+
return context.getSharedPreferences("app_preferences", Context.MODE_PRIVATE)
29+
}
30+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2018 Hossain Khan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.hossainkhan.android.demo.dagger
18+
19+
import android.app.Application
20+
import com.hossainkhan.android.demo.base.DemoApplication
21+
import dagger.BindsInstance
22+
import dagger.Component
23+
24+
@Component(modules = arrayOf(
25+
ApplicationModule::class,
26+
DataStoreModule::class,
27+
MainActivityModule::class))
28+
interface DemoApplicationComponent {
29+
fun inject(app: DemoApplication)
30+
31+
// Gives us syntactic sugar. we can then do DaggerAppComponent.builder().application(this).build().inject(this);
32+
// never having to instantiate any modules or say which module we are passing the application to.
33+
// Application will just be provided into our app graph now.
34+
@Component.Builder
35+
interface Builder {
36+
@BindsInstance
37+
fun application(application: Application): DemoApplicationComponent.Builder
38+
39+
fun build(): DemoApplicationComponent
40+
}
41+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) 2018 Hossain Khan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.hossainkhan.android.demo.dagger
18+
19+
import android.app.Activity
20+
import com.hossainkhan.android.demo.MainActivity
21+
import dagger.Binds
22+
import dagger.Module
23+
import dagger.android.ActivityKey
24+
import dagger.android.AndroidInjector
25+
import dagger.multibindings.IntoMap
26+
27+
@Module(subcomponents = arrayOf(MainActivitySubcomponent::class))
28+
abstract class MainActivityModule {
29+
30+
@Binds
31+
@IntoMap
32+
@ActivityKey(MainActivity::class)
33+
abstract fun bindMainActivityInjectorFactory(
34+
builder: MainActivitySubcomponent.Builder): AndroidInjector.Factory<out Activity>
35+
36+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright (c) 2018 Hossain Khan
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.hossainkhan.android.demo.dagger
18+
19+
import com.hossainkhan.android.demo.MainActivity
20+
import dagger.Subcomponent
21+
import dagger.android.AndroidInjector
22+
23+
@Subcomponent
24+
interface MainActivitySubcomponent : AndroidInjector<MainActivity> {
25+
@Subcomponent.Builder
26+
abstract class Builder : AndroidInjector.Builder<MainActivity>()
27+
}

0 commit comments

Comments
 (0)