refactor(android): migrate to Anvil

Fixes #261
This commit is contained in:
Harsh Shandilya 2022-11-13 13:15:24 +05:30
parent 6d88335e13
commit 4fe7c64e42
No known key found for this signature in database
16 changed files with 76 additions and 60 deletions

View file

@ -6,20 +6,15 @@
*/
@file:Suppress("DSL_SCOPE_VIOLATION", "UnstableApiUsage")
import dagger.hilt.android.plugin.HiltExtension
plugins {
id("dev.msfjarvis.claw.android-application")
id("dev.msfjarvis.claw.rename-artifacts")
id("dev.msfjarvis.claw.kotlin-android")
id("dev.msfjarvis.claw.kotlin-kapt")
id("dev.msfjarvis.claw.versioning-plugin")
alias(libs.plugins.hilt)
alias(libs.plugins.napt)
alias(libs.plugins.anvil)
}
// Hilt's aggregating task fails with NAPT
extensions.getByType<HiltExtension>().enableAggregatingTask = false
android {
namespace = "dev.msfjarvis.claw.android"
defaultConfig { applicationId = "dev.msfjarvis.claw.android" }
@ -45,13 +40,17 @@ android {
}
dependencies {
anvil(libs.tangle.viewmodel.compiler)
anvil(libs.tangle.work.compiler)
kapt(libs.dagger.compiler)
implementation(platform(libs.androidx.compose.bom))
annotationProcessor(libs.androidx.hilt.compiler)
annotationProcessor(libs.dagger.hilt.compiler)
implementation(libs.dagger)
implementation(projects.api)
implementation(projects.common)
implementation(projects.core)
implementation(projects.coroutineUtils)
implementation(projects.database)
implementation(projects.diScopes)
implementation(projects.metadataExtractor)
implementation(projects.model)
implementation(libs.accompanist.swiperefresh)
@ -59,14 +58,12 @@ dependencies {
implementation(libs.androidx.activity.compose)
implementation(libs.androidx.compose.material3)
implementation(libs.androidx.core.splashscreen)
implementation(libs.androidx.hilt.work)
implementation(libs.androidx.lifecycle.compose)
implementation(libs.androidx.navigation.compose)
implementation(libs.androidx.paging.compose)
implementation(libs.androidx.work.runtime.ktx)
implementation(libs.coil)
implementation(libs.copydown)
implementation(libs.dagger.hilt.android)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
implementation(libs.material.motion.core)
@ -74,4 +71,10 @@ dependencies {
implementation(libs.okhttp.loggingInterceptor)
implementation(libs.retrofit.kotlinxSerializationConverter)
implementation(libs.sqldelight.extensions.coroutines)
implementation(libs.tangle.viewmodel.api)
implementation(libs.tangle.viewmodel.compose) {
// https://github.com/RBusarow/Tangle/issues/558
exclude("androidx.compose.compiler")
}
implementation(libs.tangle.work.api)
}

View file

@ -0,0 +1,23 @@
/*
* Copyright © 2022 Harsh Shandilya.
* Use of this source code is governed by an MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/
package dev.msfjarvis.claw.android
import android.app.Application
import com.squareup.anvil.annotations.MergeComponent
import dagger.BindsInstance
import dagger.Component
import dev.msfjarvis.claw.injection.scopes.AppScope
import javax.inject.Singleton
@Singleton
@MergeComponent(AppScope::class)
interface AppComponent {
@Component.Factory
interface Factory {
fun create(@BindsInstance application: Application): AppComponent
}
}

View file

@ -9,33 +9,30 @@ package dev.msfjarvis.claw.android
import android.app.Application
import android.os.StrictMode
import android.util.Log
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import coil.ImageLoader
import coil.ImageLoaderFactory
import coil.disk.DiskCache
import coil.memory.MemoryCache
import dagger.hilt.android.HiltAndroidApp
import dev.msfjarvis.claw.injection.Components
import io.github.aakira.napier.DebugAntilog
import io.github.aakira.napier.Napier
import javax.inject.Inject
import tangle.inject.TangleGraph
@HiltAndroidApp
class ClawApplication : Application(), Configuration.Provider, ImageLoaderFactory {
@Inject lateinit var workerFactory: HiltWorkerFactory
override fun onCreate() {
super.onCreate()
val component = DaggerAppComponent.factory().create(this)
Components.add(component)
TangleGraph.add(component)
StrictMode.setVmPolicy(StrictMode.VmPolicy.Builder().detectAll().penaltyLog().build())
StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build())
Napier.base(DebugAntilog())
}
override fun getWorkManagerConfiguration(): Configuration {
return Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setWorkerFactory(workerFactory)
.build()
return Configuration.Builder().setMinimumLoggingLevel(Log.DEBUG).build()
}
override fun newImageLoader(): ImageLoader {

View file

@ -17,15 +17,17 @@ import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.NetworkType
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import dagger.hilt.android.AndroidEntryPoint
import dev.msfjarvis.claw.android.ui.LobstersApp
import dev.msfjarvis.claw.android.work.SavedPostUpdaterWorker
import dev.msfjarvis.claw.common.comments.HTMLConverter
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
import dev.msfjarvis.claw.injection.scopes.AppScope
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import tangle.inject.TangleGraph
import tangle.inject.TangleScope
@AndroidEntryPoint
@TangleScope(AppScope::class)
class MainActivity : ComponentActivity() {
@Inject lateinit var urlLauncher: UrlLauncher
@ -34,6 +36,7 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
TangleGraph.inject(this)
installSplashScreen()
setContent {
LobstersApp(

View file

@ -9,11 +9,11 @@ package dev.msfjarvis.claw.android.injection
import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import com.slack.eithernet.ApiResultCallAdapterFactory
import com.slack.eithernet.ApiResultConverterFactory
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dev.msfjarvis.claw.api.LobstersApi
import dev.msfjarvis.claw.injection.scopes.AppScope
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
@ -23,7 +23,7 @@ import retrofit2.create
@OptIn(ExperimentalSerializationApi::class)
@Module
@InstallIn(SingletonComponent::class)
@ContributesTo(AppScope::class)
object ApiModule {
@Provides
fun provideRetrofit(

View file

@ -6,17 +6,17 @@
*/
package dev.msfjarvis.claw.android.injection
import com.squareup.anvil.annotations.ContributesTo
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dev.msfjarvis.claw.injection.scopes.AppScope
import dev.msfjarvis.claw.util.coroutines.DefaultDispatcherProvider
import dev.msfjarvis.claw.util.coroutines.DispatcherProvider
import kotlinx.coroutines.CoroutineDispatcher
@Module
@InstallIn(SingletonComponent::class)
@ContributesTo(AppScope::class)
interface CoroutineDispatcherModule {
@Binds fun DefaultDispatcherProvider.bind(): DispatcherProvider

View file

@ -6,15 +6,15 @@
*/
package dev.msfjarvis.claw.android.injection
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dev.msfjarvis.claw.common.comments.HTMLConverter
import dev.msfjarvis.claw.injection.scopes.AppScope
import io.github.furstenheim.CopyDown
@Module
@InstallIn(SingletonComponent::class)
@ContributesTo(AppScope::class)
object HTMLConverterModule {
@Provides

View file

@ -7,14 +7,14 @@
package dev.msfjarvis.claw.android.injection
import com.chimbori.crux.Crux
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dev.msfjarvis.claw.injection.scopes.AppScope
import okhttp3.OkHttpClient
@Module
@InstallIn(SingletonComponent::class)
@ContributesTo(AppScope::class)
object MetadataExtractorModule {
@Provides
fun provideCrux(

View file

@ -8,16 +8,15 @@ package dev.msfjarvis.claw.android.injection
import android.content.Context
import android.net.TrafficStats
import com.squareup.anvil.annotations.ContributesTo
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import dagger.multibindings.IntoSet
import dev.msfjarvis.claw.android.network.DelegatingSocketFactory
import dev.msfjarvis.claw.android.network.NapierLogger
import dev.msfjarvis.claw.android.network.UserAgentInterceptor
import dev.msfjarvis.claw.injection.scopes.AppScope
import java.net.Socket
import javax.net.SocketFactory
import okhttp3.Cache
@ -26,7 +25,7 @@ import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
@Module
@InstallIn(SingletonComponent::class)
@ContributesTo(AppScope::class)
interface OkHttpModule {
@Binds fun NapierLogger.bindLogger(): HttpLoggingInterceptor.Logger
@ -38,7 +37,7 @@ interface OkHttpModule {
private const val THREAD_STATS_TAG = 0x000090000
@Provides
fun provideCache(@ApplicationContext context: Context): Cache {
fun provideCache(context: Context): Cache {
return Cache(context.cacheDir, CACHE_SIZE_MB)
}

View file

@ -7,18 +7,17 @@
package dev.msfjarvis.claw.android.injection
import android.content.Context
import com.squareup.anvil.annotations.ContributesTo
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import dagger.hilt.android.qualifiers.ActivityContext
import dev.msfjarvis.claw.common.urllauncher.UrlLauncher
import dev.msfjarvis.claw.injection.scopes.AppScope
@Module
@InstallIn(ActivityComponent::class)
@ContributesTo(AppScope::class)
object UrlLauncherModule {
@Provides
fun provideUrlLauncher(@ActivityContext context: Context): UrlLauncher {
fun provideUrlLauncher(context: Context): UrlLauncher {
return UrlLauncher(context)
}
}

View file

@ -27,7 +27,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavType
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.navArgument
@ -54,6 +53,7 @@ import kotlinx.coroutines.launch
import soup.compose.material.motion.navigation.MaterialMotionNavHost
import soup.compose.material.motion.navigation.composable
import soup.compose.material.motion.navigation.rememberMaterialMotionNavController
import tangle.viewmodel.compose.tangleViewModel
@Suppress("ModifierMissing") // Top-level composable, will never have a modifier supplied.
@OptIn(ExperimentalMaterial3Api::class, ExperimentalAnimationApi::class)
@ -62,7 +62,7 @@ fun LobstersApp(
urlLauncher: UrlLauncher,
htmlConverter: HTMLConverter,
setWebUri: (String?) -> Unit,
viewModel: ClawViewModel = viewModel(),
viewModel: ClawViewModel = tangleViewModel(),
) {
val systemUiController = rememberSystemUiController()
val hottestListState = rememberLazyListState()

View file

@ -12,7 +12,6 @@ import androidx.paging.Pager
import androidx.paging.PagingConfig
import com.slack.eithernet.ApiResult.Failure
import com.slack.eithernet.ApiResult.Success
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.msfjarvis.claw.android.injection.IODispatcher
import dev.msfjarvis.claw.android.paging.LobstersPagingSource
import dev.msfjarvis.claw.android.ui.toLocalDateTime
@ -20,16 +19,15 @@ import dev.msfjarvis.claw.api.LobstersApi
import dev.msfjarvis.claw.database.local.SavedPost
import java.io.IOException
import java.time.Month
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import tangle.viewmodel.VMInject
@HiltViewModel
class ClawViewModel
@Inject
@VMInject
constructor(
private val api: LobstersApi,
private val savedPostsRepository: SavedPostsRepository,

View file

@ -7,7 +7,6 @@
package dev.msfjarvis.claw.android.work
import android.content.Context
import androidx.hilt.work.HiltWorker
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.slack.eithernet.ApiResult
@ -20,6 +19,7 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.supervisorScope
import tangle.work.TangleWorker
/**
* WorkManager-backed [CoroutineWorker] that gets all the posts from [SavedPostsRepository], fetches
@ -27,7 +27,7 @@ import kotlinx.coroutines.supervisorScope
* saved posts that were saved before comment counts were added to be able to show a comment count
* and for new-enough posts that are still getting comments to have an accurate one.
*/
@HiltWorker
@TangleWorker
class SavedPostUpdaterWorker
@AssistedInject
constructor(

View file

@ -10,6 +10,5 @@ plugins {
id("dev.msfjarvis.claw.spotless")
id("dev.msfjarvis.claw.versions")
id("dev.msfjarvis.claw.kotlin-common")
alias(libs.plugins.hilt) apply false
alias(libs.plugins.android.test) apply false
}

View file

@ -7,7 +7,6 @@ coil = "2.2.2"
composeCompiler = "1.4.0-alpha02"
coroutines = "1.6.4"
dagger = "2.44.1"
hilt = "1.0.0"
kotlin = "1.7.21"
material_motion = "0.10.3"
# @pin Needs to be aligned with Retrofit
@ -37,8 +36,6 @@ androidx-compose-ui-text = { module = "androidx.compose.ui:ui-text" }
androidx-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" }
androidx-core-splashscreen = "androidx.core:core-splashscreen:1.0.0"
androidx-hilt-compiler = { module = "androidx.hilt:hilt-compiler", version.ref = "hilt" }
androidx-hilt-work = { module = "androidx.hilt:hilt-work", version.ref = "hilt" }
androidx-lifecycle-compose = "androidx.lifecycle:lifecycle-viewmodel-compose:2.6.0-alpha03"
androidx-navigation-compose = "androidx.navigation:navigation-compose:2.6.0-alpha04"
androidx-paging-compose = "androidx.paging:paging-compose:1.0.0-alpha17"
@ -68,9 +65,6 @@ copydown = "io.github.furstenheim:copy_down:1.1"
crux = "com.chimbori.crux:crux:3.11.0"
dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" }
dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" }
dagger-hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "dagger" }
dagger-hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "dagger" }
dagger-hilt-core = { module = "com.google.dagger:hilt-core", version.ref = "dagger" }
eithernet = "com.slack.eithernet:eithernet:1.2.1"
javapoet = "com.squareup:javapoet:1.13.0"
javax-inject = "javax.inject:javax.inject:1"
@ -98,7 +92,6 @@ testparameterinjector = "com.google.testparameterinjector:test-parameter-injecto
[plugins]
android-test = { id = "com.android.test", version.ref = "agp" }
hilt = { id = "com.google.dagger.hilt.android", version.ref = "dagger" }
anvil = "com.squareup.anvil:2.4.2"
napt = "com.sergei-lapin.napt:1.18"
sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }

View file

@ -140,8 +140,10 @@ include(
"api",
"benchmark",
"common",
"core",
"coroutine-utils",
"database",
"di-scopes",
"metadata-extractor",
"model",
)