Skip to content

Commit 0c155b8

Browse files
committed
Refactor project to replace Dagger Hilt with Koin for dependency injection
- Removed Dagger Hilt dependencies and annotations across multiple modules. - Integrated Koin for dependency injection, updating ViewModels and repositories accordingly. - Updated ProGuard rules to accommodate changes in dependency management. - Incremented version code and name in build.gradle.kts for the upcoming release. - Enhanced various Gradle files to ensure compatibility with new dependencies.
1 parent e7da11a commit 0c155b8

File tree

41 files changed

+488
-409
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+488
-409
lines changed

app/build.gradle.kts

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ plugins {
44
alias(libs.plugins.android.application)
55
alias(libs.plugins.org.jetbrains.kotlin.android)
66
alias(libs.plugins.com.google.devtools.ksp)
7-
alias(libs.plugins.dagger.hilt)
87
alias(libs.plugins.compose.compiler)
98
}
109

@@ -16,8 +15,8 @@ android {
1615
applicationId = "com.arklan.weather"
1716
minSdk = ConfigData.minSdk
1817
targetSdk = ConfigData.targetSdk
19-
versionCode = 17
20-
versionName = "2.6.1"
18+
versionCode = 18
19+
versionName = "2.6.2"
2120
setProperty("archivesBaseName", "weekly-weather-v$versionName.$versionCode")
2221

2322
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
@@ -26,15 +25,14 @@ android {
2625
}
2726
}
2827

29-
30-
3128
buildTypes {
3229
release {
3330
isMinifyEnabled = ConfigData.isMinifyRelease
3431
proguardFiles(
3532
getDefaultProguardFile("proguard-android-optimize.txt"),
3633
"proguard-rules.pro"
3734
)
35+
isShrinkResources = true
3836
}
3937
debug {
4038
isMinifyEnabled = ConfigData.isMinifyDebug
@@ -60,9 +58,6 @@ android {
6058
excludes += "/META-INF/{AL2.0,LGPL2.1}"
6159
}
6260
}
63-
hilt {
64-
enableAggregatingTask = true
65-
}
6661
}
6762

6863
dependencies {
@@ -87,10 +82,10 @@ dependencies {
8782
implementation(libs.androidx.compose.graphics)
8883
implementation(libs.androidx.compose.tooling.preview)
8984

90-
//Dagger - Hilt
91-
implementation(libs.hilt.android)
92-
implementation(libs.hilt.navigation.compose)
93-
ksp(libs.hilt.android.compiler)
85+
// Koin
86+
implementation(libs.koin.android)
87+
implementation(libs.koin.androidx.compose)
88+
implementation(libs.koin.androidx.compose.navigation)
9489

9590
implementation(libs.coroutines.test)
9691
testImplementation(libs.junit.junit)

app/proguard-rules.pro

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,81 @@
3535
-keep class com.codeskraps.maps.** { *; }
3636
-keep class com.codeskraps.umami.** { *; }
3737

38+
# Additional dontwarn rules from missing_rules.txt
39+
-dontwarn com.codeskraps.feature.geocoding.di.FeatureModuleKt
40+
-dontwarn com.codeskraps.feature.weather.di.FeatureModuleKt
41+
42+
# Koin
43+
-keepnames class android.arch.lifecycle.ViewModel
44+
-keepclassmembers public class * extends android.arch.lifecycle.ViewModel { public <init>(...); }
45+
-keepclassmembers class com.codeskraps.** { public <init>(...); }
46+
-keepclassmembers class * { @org.koin.core.annotation.KoinInternalApi *; }
47+
-keep class org.koin.** { *; }
48+
-keep class com.codeskraps.**.di.** { *; }
49+
-keep class * extends org.koin.core.module.Module { *; }
50+
51+
# Keep Koin Modules
52+
-keep class com.codeskraps.feature.geocoding.di.FeatureModuleKt { *; }
53+
-keep class com.codeskraps.feature.maps.di.FeatureModuleKt { *; }
54+
-keep class com.codeskraps.feature.weather.di.FeatureModuleKt { *; }
55+
3856
# Java language APIs
3957
-dontwarn java.lang.invoke.StringConcatFactory
4058

59+
# Hilt ViewModel classes
60+
-keep class * extends androidx.lifecycle.ViewModel { *; }
61+
-keep class * extends dagger.hilt.android.lifecycle.HiltViewModel { *; }
62+
-keep,allowobfuscation @dagger.hilt.android.lifecycle.HiltViewModel class *
63+
-keepclasseswithmembers class * {
64+
@javax.inject.Inject <init>(...);
65+
}
66+
67+
# Explicitly keep Hilt generated ViewModel classes
68+
-keep class com.codeskraps.feature.geocoding.presentation.GeocodingViewModel_HiltModules$* { *; }
69+
-keep class com.codeskraps.feature.weather.presentation.WeatherViewModel_HiltModules$* { *; }
70+
-keep class com.codeskraps.maps.presentation.MapViewModel_HiltModules$* { *; }
71+
72+
# Keep all Hilt related classes
73+
-keep class com.codeskraps.weather.WeatherApp_HiltComponents$* { *; }
74+
-keep class dagger.hilt.** { *; }
75+
-keep class javax.inject.** { *; }
76+
-keep class * extends dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper { *; }
77+
78+
# Keep Dagger components
79+
-keep,allowobfuscation,allowshrinking @dagger.** class *
80+
-keep,allowobfuscation,allowshrinking class dagger.** { *; }
81+
-keep,allowobfuscation,allowshrinking class javax.inject.** { *; }
82+
-keep,allowobfuscation,allowshrinking class * extends dagger.internal.Factory { *; }
83+
-keepclassmembers,allowobfuscation class * {
84+
@javax.inject.* *;
85+
@dagger.* *;
86+
<init>();
87+
}
88+
89+
# Keep all generated Hilt code
90+
-keep class **_HiltModules$* { *; }
91+
-keep class **_Impl { *; }
92+
-keep class **_Factory { *; }
93+
-keep class **_MembersInjector { *; }
94+
95+
# Keep specific Hilt ViewModel components
96+
-keep class com.codeskraps.feature.geocoding.presentation.GeocodingViewModel_HiltModules$BindsModule { *; }
97+
-keep class com.codeskraps.feature.geocoding.presentation.GeocodingViewModel_HiltModules$KeyModule { *; }
98+
-keep class com.codeskraps.feature.weather.presentation.WeatherViewModel_HiltModules$BindsModule { *; }
99+
-keep class com.codeskraps.feature.weather.presentation.WeatherViewModel_HiltModules$KeyModule { *; }
100+
-keep class com.codeskraps.maps.presentation.MapViewModel_HiltModules$BindsModule { *; }
101+
-keep class com.codeskraps.maps.presentation.MapViewModel_HiltModules$KeyModule { *; }
102+
103+
# Keep Hilt ViewModel factories
104+
-keep class com.codeskraps.feature.geocoding.presentation.GeocodingViewModel_Factory { *; }
105+
-keep class com.codeskraps.feature.weather.presentation.WeatherViewModel_Factory { *; }
106+
-keep class com.codeskraps.maps.presentation.MapViewModel_Factory { *; }
107+
108+
# Keep Hilt ViewModel members injectors
109+
-keep class com.codeskraps.feature.geocoding.presentation.GeocodingViewModel_MembersInjector { *; }
110+
-keep class com.codeskraps.feature.weather.presentation.WeatherViewModel_MembersInjector { *; }
111+
-keep class com.codeskraps.maps.presentation.MapViewModel_MembersInjector { *; }
112+
41113
# Additionally, adding specific rules from the missing_rules.txt
42114
-dontwarn com.codeskraps.core.local.data.repository.LocalGeocodingRepositoryImpl
43115
-dontwarn com.codeskraps.core.local.data.repository.LocalResourceRepositoryImpl
@@ -57,7 +129,6 @@
57129
-dontwarn com.codeskraps.feature.geocoding.data.repository.GeocodingRepositoryImpl
58130
-dontwarn com.codeskraps.feature.geocoding.di.FeatureModule_ProvidesGeocodingApiFactory
59131
-dontwarn com.codeskraps.feature.geocoding.presentation.GeocodingViewModel
60-
-dontwarn com.codeskraps.feature.geocoding.presentation.GeocodingViewModel_HiltModules$KeyModule
61132
-dontwarn com.codeskraps.feature.geocoding.presentation.components.GeocodingScreenKt
62133
-dontwarn com.codeskraps.feature.geocoding.presentation.mvi.GeoEvent
63134
-dontwarn com.codeskraps.feature.geocoding.presentation.mvi.GeoState
@@ -67,12 +138,10 @@
67138
-dontwarn com.codeskraps.feature.weather.di.FeatureModule_ProvidesWeatherApiFactory
68139
-dontwarn com.codeskraps.feature.weather.domain.repository.WeatherRepository
69140
-dontwarn com.codeskraps.feature.weather.presentation.WeatherViewModel
70-
-dontwarn com.codeskraps.feature.weather.presentation.WeatherViewModel_HiltModules$KeyModule
71141
-dontwarn com.codeskraps.feature.weather.presentation.components.WeatherScreenKt
72142
-dontwarn com.codeskraps.feature.weather.presentation.mvi.WeatherEvent
73143
-dontwarn com.codeskraps.feature.weather.presentation.mvi.WeatherState
74144
-dontwarn com.codeskraps.maps.presentation.MapViewModel
75-
-dontwarn com.codeskraps.maps.presentation.MapViewModel_HiltModules$KeyModule
76145
-dontwarn com.codeskraps.maps.presentation.components.MapScreenKt
77146
-dontwarn com.codeskraps.maps.presentation.mvi.MapEvent
78147
-dontwarn com.codeskraps.maps.presentation.mvi.MapState
Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,33 @@
11
package com.codeskraps.weather
22

33
import android.app.Application
4-
import dagger.hilt.android.HiltAndroidApp
4+
import com.codeskraps.core.local.di.localModule
5+
import com.codeskraps.core.location.di.locationModule
6+
import com.codeskraps.feature.common.di.commonModule
7+
import com.codeskraps.feature.geocoding.di.geocodingModule
8+
import com.codeskraps.feature.weather.di.weatherModule
9+
import com.codeskraps.maps.di.mapsFeatureModule
10+
import com.codeskraps.umami.di.umamiModule
11+
import org.koin.android.ext.koin.androidContext
12+
import org.koin.android.ext.koin.androidLogger
13+
import org.koin.core.context.startKoin
514

6-
@HiltAndroidApp
7-
class WeatherApp : Application()
15+
class WeatherApp : Application() {
16+
override fun onCreate() {
17+
super.onCreate()
18+
19+
startKoin {
20+
androidLogger()
21+
androidContext(this@WeatherApp)
22+
modules(
23+
commonModule,
24+
localModule,
25+
locationModule,
26+
geocodingModule,
27+
weatherModule,
28+
mapsFeatureModule,
29+
umamiModule
30+
)
31+
}
32+
}
33+
}

app/src/main/java/com/codeskraps/weather/ui/MainActivity.kt

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import androidx.compose.animation.AnimatedContentTransitionScope
99
import androidx.compose.animation.core.tween
1010
import androidx.compose.runtime.getValue
1111
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
12-
import androidx.hilt.navigation.compose.hiltViewModel
1312
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1413
import androidx.lifecycle.lifecycleScope
1514
import androidx.navigation.NavType
@@ -27,15 +26,13 @@ import com.codeskraps.maps.presentation.components.MapScreen
2726
import com.codeskraps.umami.domain.AnalyticsRepository
2827
import com.codeskraps.weather.ui.theme.ScreenTransitions
2928
import com.codeskraps.weather.ui.theme.WeatherTheme
30-
import dagger.hilt.android.AndroidEntryPoint
3129
import kotlinx.coroutines.launch
32-
import javax.inject.Inject
30+
import org.koin.android.ext.android.inject
31+
import org.koin.androidx.compose.koinViewModel
3332

34-
@AndroidEntryPoint
3533
class MainActivity : ComponentActivity() {
3634

37-
@Inject
38-
lateinit var analyticsRepository: AnalyticsRepository
35+
private val analyticsRepository: AnalyticsRepository by inject()
3936

4037
private var isAnalyticsInitialized = false
4138

@@ -94,7 +91,7 @@ class MainActivity : ComponentActivity() {
9491
popEnterTransition = { ScreenTransitions.slideRightIntoContainer(this) },
9592
popExitTransition = { ScreenTransitions.slideLeftOutOfContainer(this) }
9693
) {
97-
val viewModel = hiltViewModel<WeatherViewModel>()
94+
val viewModel = koinViewModel<WeatherViewModel>()
9895
val state by viewModel.state.collectAsStateWithLifecycle()
9996

10097
WeatherScreen(
@@ -112,7 +109,7 @@ class MainActivity : ComponentActivity() {
112109
popEnterTransition = { ScreenTransitions.slideLeftIntoContainer(this) },
113110
popExitTransition = { ScreenTransitions.slideRightOutOfContainer(this) }
114111
) {
115-
val viewModel = hiltViewModel<GeocodingViewModel>()
112+
val viewModel = koinViewModel<GeocodingViewModel>()
116113
val state by viewModel.state.collectAsStateWithLifecycle()
117114

118115
GeocodingScreen(
@@ -142,23 +139,17 @@ class MainActivity : ComponentActivity() {
142139
}
143140
) {
144141
Log.d("Navigation", "Attempting to navigate to Map screen")
145-
val viewModel = hiltViewModel<MapViewModel>()
142+
val viewModel = koinViewModel<MapViewModel>()
146143
val state by viewModel.state.collectAsStateWithLifecycle()
147144
MapScreen(
148145
state = state,
149146
handleEvent = viewModel.state::handleEvent,
150147
action = viewModel.action,
151148
navRoute = { route ->
152-
when (route) {
153-
"nav_up" -> {
154-
Log.d("Navigation", "Map screen navigation up")
155-
navController.navigateUp()
156-
}
157-
158-
else -> {
159-
Log.d("Navigation", "Map screen navigation to $route")
160-
navController.navigate(route)
161-
}
149+
if (route == "nav_up") {
150+
navController.navigateUp()
151+
} else {
152+
navController.navigate(route)
162153
}
163154
}
164155
)

build.gradle.kts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ plugins {
33
alias(libs.plugins.android.library) apply false
44
alias(libs.plugins.org.jetbrains.kotlin.android) apply false
55
alias(libs.plugins.com.google.devtools.ksp) apply false
6-
alias(libs.plugins.dagger.hilt) apply false
7-
alias(libs.plugins.secrets.gradle.plugin) apply false
86
alias(libs.plugins.compose.compiler) apply false
7+
alias(libs.plugins.secrets.gradle.plugin) apply false
98
}
109

1110
tasks.register("clean", Delete::class) {

core/local/build.gradle.kts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ plugins {
44
alias(libs.plugins.android.library)
55
alias(libs.plugins.org.jetbrains.kotlin.android)
66
alias(libs.plugins.com.google.devtools.ksp)
7-
alias(libs.plugins.dagger.hilt)
87
}
98

109
android {
@@ -46,15 +45,14 @@ dependencies {
4645
implementation(libs.appcompat)
4746
implementation(libs.material)
4847

49-
//Dagger - Hilt
50-
implementation(libs.hilt.android)
51-
ksp(libs.hilt.android.compiler)
52-
5348
// Room
5449
implementation(libs.room.runtime)
55-
annotationProcessor(libs.room.compiler)
50+
implementation(libs.androidx.room.ktx)
5651
ksp(libs.room.compiler)
5752

53+
// Koin
54+
implementation(libs.koin.android)
55+
5856
testImplementation(libs.junit.junit)
5957
androidTestImplementation(libs.androidx.junit)
6058
androidTestImplementation(libs.espresso.core)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.codeskraps.core.local.data.dao
2+
3+
import androidx.room.Dao
4+
import androidx.room.Delete
5+
import androidx.room.Insert
6+
import androidx.room.OnConflictStrategy
7+
import androidx.room.Query
8+
import com.codeskraps.core.local.data.model.GeoLocationEntity
9+
10+
@Dao
11+
interface GeoLocationDao {
12+
@Query("SELECT * FROM GeoLocationEntity")
13+
suspend fun getAll(): List<GeoLocationEntity>
14+
15+
@Query("SELECT * FROM GeoLocationEntity WHERE latitude = :latitude AND longitude = :longitude")
16+
suspend fun getByLocation(latitude: Double, longitude: Double): List<GeoLocationEntity>
17+
18+
@Insert(onConflict = OnConflictStrategy.REPLACE)
19+
suspend fun insert(geoLocation: GeoLocationEntity)
20+
21+
@Delete
22+
suspend fun delete(geoLocation: GeoLocationEntity)
23+
24+
@Query("DELETE FROM GeoLocationEntity WHERE latitude = :latitude AND longitude = :longitude")
25+
suspend fun delete(latitude: Double, longitude: Double)
26+
}
Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
11
package com.codeskraps.core.local.data.db
22

3+
import android.content.Context
34
import androidx.room.Database
5+
import androidx.room.Room
46
import androidx.room.RoomDatabase
7+
import com.codeskraps.core.local.data.dao.GeoLocationDao
58
import com.codeskraps.core.local.data.model.GeoLocationEntity
69

710
@Database(
811
entities = [GeoLocationEntity::class],
912
version = 1,
1013
exportSchema = false
1114
)
12-
abstract class GeocodingDB: RoomDatabase() {
15+
abstract class GeocodingDB : RoomDatabase() {
16+
abstract fun geocodingDao(): GeoLocationDao
1317

14-
abstract fun geocodingDao(): GeocodingDao
18+
companion object {
19+
@Volatile
20+
private var INSTANCE: GeocodingDB? = null
21+
22+
fun getInstance(context: Context): GeocodingDB {
23+
return INSTANCE ?: synchronized(this) {
24+
val instance = Room.databaseBuilder(
25+
context.applicationContext,
26+
GeocodingDB::class.java,
27+
"geocoding_database"
28+
).build()
29+
INSTANCE = instance
30+
instance
31+
}
32+
}
33+
}
1534
}

0 commit comments

Comments
 (0)