Continue setting up dagger

This commit is contained in:
ganfra 2022-12-14 16:11:04 +01:00
parent 4452abb461
commit b7f84f65a8
14 changed files with 177 additions and 31 deletions

View file

@ -3,6 +3,7 @@ plugins {
alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.android)
alias(libs.plugins.ksp) alias(libs.plugins.ksp)
alias(libs.plugins.anvil) alias(libs.plugins.anvil)
alias(libs.plugins.kapt)
id("com.google.firebase.appdistribution") version "3.0.2" id("com.google.firebase.appdistribution") version "3.0.2"
} }
@ -101,16 +102,16 @@ android {
} }
} }
kotlin { applicationVariants.all {
sourceSets.main { kotlin.sourceSets {
kotlin.srcDir("build/generated/ksp/main/kotlin") getByName(name) {
} kotlin.srcDir("build/generated/ksp/$name/kotlin")
sourceSets.test { }
kotlin.srcDir("build/generated/ksp/test/kotlin")
} }
} }
} }
dependencies { dependencies {
implementation(project(":libraries:designsystem")) implementation(project(":libraries:designsystem"))
implementation(project(":libraries:matrix")) implementation(project(":libraries:matrix"))
@ -119,6 +120,7 @@ dependencies {
implementation(project(":features:login")) implementation(project(":features:login"))
implementation(project(":features:roomlist")) implementation(project(":features:roomlist"))
implementation(project(":features:messages")) implementation(project(":features:messages"))
implementation(project(":libraries:daggerscopes"))
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.0") coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.2.0")
implementation(libs.compose.destinations) implementation(libs.compose.destinations)
@ -128,11 +130,13 @@ dependencies {
implementation(libs.androidx.lifecycle.runtime) implementation(libs.androidx.lifecycle.runtime)
implementation(libs.androidx.lifecycle.viewmodel.compose) implementation(libs.androidx.lifecycle.viewmodel.compose)
implementation(libs.androidx.activity.compose) implementation(libs.androidx.activity.compose)
implementation(libs.androidx.startup)
implementation(libs.coil) implementation(libs.coil)
implementation(libs.timber) implementation(libs.timber)
implementation(libs.mavericks.compose) implementation(libs.mavericks.compose)
implementation(libs.dagger) implementation(libs.dagger)
kapt(libs.dagger.compiler)
implementation(libs.showkase) implementation(libs.showkase)
ksp(libs.showkase.processor) ksp(libs.showkase.processor)

View file

@ -26,6 +26,15 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="remove"/>
</application> </application>
</manifest> </manifest>

View file

@ -1,32 +1,31 @@
package io.element.android.x package io.element.android.x
import android.app.Application import android.app.Application
import coil.ImageLoader import androidx.startup.AppInitializer
import coil.ImageLoaderFactory import io.element.android.x.core.di.DaggerComponentOwner
import com.airbnb.mvrx.Mavericks import io.element.android.x.di.DaggerAppComponent
import io.element.android.x.initializer.CoilInitializer
import io.element.android.x.initializer.MavericksInitializer
import io.element.android.x.initializer.TimberInitializer
import io.element.android.x.matrix.MatrixInstance import io.element.android.x.matrix.MatrixInstance
import kotlinx.coroutines.CoroutineName import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.plus import kotlinx.coroutines.plus
import timber.log.Timber
class ElementXApplication : Application(), ImageLoaderFactory { class ElementXApplication : Application(), DaggerComponentOwner {
override lateinit var daggerComponent: Any
private val applicationScope = MainScope() + CoroutineName("ElementX Scope") private val applicationScope = MainScope() + CoroutineName("ElementX Scope")
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
Timber.plant(Timber.DebugTree()) daggerComponent = DaggerAppComponent.factory().create(this)
MatrixInstance.init(this, applicationScope) MatrixInstance.init(this, applicationScope)
Mavericks.initialize(this) AppInitializer.getInstance(this).apply {
initializeComponent(TimberInitializer::class.java)
initializeComponent(CoilInitializer::class.java)
initializeComponent(MavericksInitializer::class.java)
}
} }
}
override fun newImageLoader(): ImageLoader {
return ImageLoader
.Builder(this)
.components {
MatrixInstance.getInstance().registerComponents(this)
}
.build()
}
}

View file

@ -32,8 +32,11 @@ import com.google.accompanist.navigation.material.ExperimentalMaterialNavigation
import com.ramcosta.composedestinations.DestinationsNavHost import com.ramcosta.composedestinations.DestinationsNavHost
import com.ramcosta.composedestinations.animations.defaults.RootNavGraphDefaultAnimations import com.ramcosta.composedestinations.animations.defaults.RootNavGraphDefaultAnimations
import com.ramcosta.composedestinations.animations.rememberAnimatedNavHostEngine import com.ramcosta.composedestinations.animations.rememberAnimatedNavHostEngine
import com.ramcosta.composedestinations.manualcomposablecalls.animatedComposable
import com.ramcosta.composedestinations.navigation.dependency
import com.ramcosta.composedestinations.spec.Route import com.ramcosta.composedestinations.spec.Route
import io.element.android.x.core.compose.OnLifecycleEvent import io.element.android.x.core.compose.OnLifecycleEvent
import io.element.android.x.core.di.DaggerComponentOwner
import io.element.android.x.designsystem.ElementXTheme import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.destinations.OnBoardingScreenNavigationDestination import io.element.android.x.destinations.OnBoardingScreenNavigationDestination
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
@ -147,7 +150,10 @@ class MainActivity : ComponentActivity() {
engine = engine, engine = engine,
navController = navController, navController = navController,
navGraph = NavGraphs.root, navGraph = NavGraphs.root,
startRoute = startRoute startRoute = startRoute,
dependenciesContainerBuilder = {
}
) )
} }

View file

@ -0,0 +1,12 @@
package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesTo
import io.element.android.x.di.AppScope
import io.element.android.x.matrix.Matrix
import kotlinx.coroutines.CoroutineScope
@ContributesTo(AppScope::class)
interface AppBindings {
fun coroutineScope(): CoroutineScope
fun matrix(): Matrix
}

View file

@ -0,0 +1,16 @@
package io.element.android.x.di
import android.app.Application
import com.squareup.anvil.annotations.MergeComponent
import dagger.BindsInstance
import dagger.Component
@SingleIn(AppScope::class)
@MergeComponent(AppScope::class)
interface AppComponent {
@Component.Factory
interface Factory {
fun create(@BindsInstance application: Application): AppComponent
}
}

View file

@ -0,0 +1,20 @@
package io.element.android.x.di
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
import dagger.Provides
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.plus
@Module
@ContributesTo(AppScope::class)
object AppModule {
@Provides
@SingleIn(AppScope::class)
fun providesAppCoroutineScope(): CoroutineScope {
return MainScope() + CoroutineName("ElementX Scope")
}
}

View file

@ -0,0 +1,36 @@
package io.element.android.x.initializer
import android.content.Context
import androidx.startup.Initializer
import coil.Coil
import coil.ImageLoader
import coil.ImageLoaderFactory
import io.element.android.x.core.di.DaggerComponentOwner
import io.element.android.x.core.di.bindings
import io.element.android.x.di.AppBindings
import io.element.android.x.di.AppComponent
class CoilInitializer : Initializer<Unit> {
override fun create(context: Context) {
Coil.setImageLoader(ElementImageLoaderFactory(context))
}
override fun dependencies(): MutableList<Class<out Initializer<*>>> = mutableListOf()
}
private class ElementImageLoaderFactory(
private val context: Context
) :
ImageLoaderFactory {
override fun newImageLoader(): ImageLoader {
return ImageLoader
.Builder(context)
.components {
context.bindings<AppBindings>().matrix().registerCoilComponents(this)
}
.build()
}
}

View file

@ -0,0 +1,16 @@
package io.element.android.x.initializer
import android.content.Context
import androidx.startup.Initializer
import com.airbnb.mvrx.Mavericks
class MavericksInitializer : Initializer<Unit> {
override fun create(context: Context) {
Mavericks.initialize(context)
}
override fun dependencies(): MutableList<Class<out Initializer<*>>> = mutableListOf()
}

View file

@ -0,0 +1,14 @@
package io.element.android.x.initializer
import android.content.Context
import androidx.startup.Initializer
import timber.log.Timber
class TimberInitializer: Initializer<Unit> {
override fun create(context: Context) {
Timber.plant(Timber.DebugTree())
}
override fun dependencies(): MutableList<Class<out Initializer<*>>> = mutableListOf()
}

View file

@ -14,6 +14,7 @@ recyclerview = "1.2.1"
lifecycle = "2.5.1" lifecycle = "2.5.1"
activity_compose = "1.6.1" activity_compose = "1.6.1"
fragment = "1.5.5" fragment = "1.5.5"
startup = "1.1.1"
# Compose # Compose
compose_compiler = "1.3.2" compose_compiler = "1.3.2"
@ -48,7 +49,7 @@ compose_destinations = "1.7.23-beta"
jsoup = "1.15.3" jsoup = "1.15.3"
# DI # DI
dagger = "2.32" dagger = "2.43"
anvil = "2.4.2" anvil = "2.4.2"
[libraries] [libraries]
@ -68,6 +69,7 @@ androidx_lifecycle_runtime = { module = "androidx.lifecycle:lifecycle-runtime-kt
androidx_lifecycle_viewmodel_compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" } androidx_lifecycle_viewmodel_compose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
androidx_activity_compose = { module = "androidx.activity:activity-compose", version.ref = "activity_compose" } androidx_activity_compose = { module = "androidx.activity:activity-compose", version.ref = "activity_compose" }
androidx_fragment = {module = "androidx.fragment:fragment-ktx", version.ref = "fragment"} androidx_fragment = {module = "androidx.fragment:fragment-ktx", version.ref = "fragment"}
androidx_startup = { module = "androidx.startup:startup-runtime", version.ref = "startup"}
androidx_compose_bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose_bom" } androidx_compose_bom = { group = "androidx.compose", name = "compose-bom", version.ref = "compose_bom" }
androidx_compose_foundation = { group = "androidx.compose.foundation", name = "foundation" } androidx_compose_foundation = { group = "androidx.compose.foundation", name = "foundation" }
@ -111,9 +113,11 @@ showkase = { module = "com.airbnb.android:showkase", version.ref = "showkase" }
showkase_processor = { module = "com.airbnb.android:showkase-processor", version.ref = "showkase" } showkase_processor = { module = "com.airbnb.android:showkase-processor", version.ref = "showkase" }
jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" } jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" }
# Di # Di
inject = {module = "javax.inject:javax.inject", version = "1"} inject = {module = "javax.inject:javax.inject", version = "1"}
dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" } dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" }
dagger_compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" }
anvil_compiler_api = { module = "com.squareup.anvil:compiler-api", version.ref = "anvil" } anvil_compiler_api = { module = "com.squareup.anvil:compiler-api", version.ref = "anvil" }
anvil_compiler_utils = { module = "com.squareup.anvil:compiler-utils", version.ref = "anvil" } anvil_compiler_utils = { module = "com.squareup.anvil:compiler-utils", version.ref = "anvil" }

View file

@ -1,5 +1,6 @@
plugins { plugins {
id("io.element.android-library") id("io.element.android-library")
alias(libs.plugins.anvil)
kotlin("plugin.serialization") version "1.7.20" kotlin("plugin.serialization") version "1.7.20"
} }
@ -7,8 +8,13 @@ android {
namespace = "io.element.android.x.sdk.matrix" namespace = "io.element.android.x.sdk.matrix"
} }
anvil {
generateDaggerFactories.set(true)
}
dependencies { dependencies {
api(project(":libraries:rustsdk")) api(project(":libraries:rustsdk"))
implementation(project(":libraries:daggerscopes"))
implementation(project(":libraries:core")) implementation(project(":libraries:core"))
implementation(libs.timber) implementation(libs.timber)
implementation("net.java.dev.jna:jna:5.12.1@aar") implementation("net.java.dev.jna:jna:5.12.1@aar")

View file

@ -1,8 +1,10 @@
package io.element.android.x.matrix package io.element.android.x.matrix
import android.content.Context import android.app.Application
import coil.ComponentRegistry import coil.ComponentRegistry
import io.element.android.x.core.coroutine.CoroutineDispatchers import io.element.android.x.core.coroutine.CoroutineDispatchers
import io.element.android.x.di.AppScope
import io.element.android.x.di.SingleIn
import io.element.android.x.matrix.media.MediaFetcher import io.element.android.x.matrix.media.MediaFetcher
import io.element.android.x.matrix.media.MediaKeyer import io.element.android.x.matrix.media.MediaKeyer
import io.element.android.x.matrix.session.SessionStore import io.element.android.x.matrix.session.SessionStore
@ -19,10 +21,12 @@ import timber.log.Timber
import java.io.File import java.io.File
import java.util.* import java.util.*
import java.util.concurrent.Executors import java.util.concurrent.Executors
import javax.inject.Inject
class Matrix( @SingleIn(AppScope::class)
class Matrix @Inject constructor(
private val coroutineScope: CoroutineScope, private val coroutineScope: CoroutineScope,
context: Context, context: Application,
) { ) {
private val coroutineDispatchers = CoroutineDispatchers( private val coroutineDispatchers = CoroutineDispatchers(
io = Dispatchers.IO, io = Dispatchers.IO,
@ -58,7 +62,7 @@ class Matrix(
return matrixClient.value.get() return matrixClient.value.get()
} }
fun registerComponents(builder: ComponentRegistry.Builder) { fun registerCoilComponents(builder: ComponentRegistry.Builder) {
builder.add(MediaKeyer()) builder.add(MediaKeyer())
builder.add(MediaFetcher.Factory(this)) builder.add(MediaFetcher.Factory(this))
} }

View file

@ -1,7 +1,7 @@
package io.element.android.x.matrix package io.element.android.x.matrix
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.Context import android.app.Application
import io.element.android.x.matrix.tracing.TracingConfigurations import io.element.android.x.matrix.tracing.TracingConfigurations
import io.element.android.x.matrix.tracing.setupTracing import io.element.android.x.matrix.tracing.setupTracing
import io.element.android.x.sdk.matrix.BuildConfig import io.element.android.x.sdk.matrix.BuildConfig
@ -12,7 +12,7 @@ object MatrixInstance {
@SuppressLint("StaticFieldLeak") @SuppressLint("StaticFieldLeak")
private lateinit var instance: Matrix private lateinit var instance: Matrix
fun init(context: Context, coroutineScope: CoroutineScope) { fun init(context: Application, coroutineScope: CoroutineScope) {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
setupTracing(TracingConfigurations.debug) setupTracing(TracingConfigurations.debug)
} else { } else {