adding DepedencyInjnection with HILT
This commit is contained in:
@@ -2,6 +2,12 @@ plugins {
|
||||
id("com.android.application")
|
||||
id("org.jetbrains.kotlin.android")
|
||||
id("androidx.navigation.safeargs.kotlin")
|
||||
id("kotlin-kapt")
|
||||
id("com.google.dagger.hilt.android")
|
||||
}
|
||||
|
||||
kapt {
|
||||
correctErrorTypes = true
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -11,6 +17,12 @@ android {
|
||||
lint {
|
||||
abortOnError = false
|
||||
}
|
||||
|
||||
packaging {
|
||||
resources {
|
||||
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = "com.mattintech.lchat"
|
||||
@@ -50,6 +62,7 @@ android {
|
||||
}
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
buildConfig = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +79,10 @@ dependencies {
|
||||
implementation("androidx.navigation:navigation-fragment-ktx:2.7.6")
|
||||
implementation("androidx.navigation:navigation-ui-ktx:2.7.6")
|
||||
|
||||
// Hilt dependencies
|
||||
implementation("com.google.dagger:hilt-android:2.50")
|
||||
kapt("com.google.dagger:hilt-compiler:2.50")
|
||||
|
||||
testImplementation("junit:junit:4.13.2")
|
||||
androidTestImplementation("androidx.test.ext:junit:1.1.5")
|
||||
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
|
||||
|
||||
15
app/proguard-rules.pro
vendored
15
app/proguard-rules.pro
vendored
@@ -11,4 +11,17 @@
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
#-renamesourcefileattribute SourceFile
|
||||
|
||||
# Keep Application class
|
||||
-keep class com.mattintech.lchat.LChatApplication { *; }
|
||||
|
||||
# Hilt rules
|
||||
-keep class dagger.hilt.** { *; }
|
||||
-keep class javax.inject.** { *; }
|
||||
-keep class * extends dagger.hilt.android.internal.managers.ViewComponentManager { *; }
|
||||
|
||||
# Keep all @HiltAndroidApp, @AndroidEntryPoint, @HiltViewModel annotated classes
|
||||
-keep @dagger.hilt.android.HiltAndroidApp class * { *; }
|
||||
-keep @dagger.hilt.android.AndroidEntryPoint class * { *; }
|
||||
-keep @dagger.hilt.android.lifecycle.HiltViewModel class * { *; }
|
||||
@@ -15,6 +15,7 @@
|
||||
<uses-feature android:name="android.hardware.wifi.aware" android:required="true" />
|
||||
|
||||
<application
|
||||
android:name=".LChatApplication"
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
|
||||
11
app/src/main/java/com/mattintech/lchat/LChatApplication.kt
Normal file
11
app/src/main/java/com/mattintech/lchat/LChatApplication.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
package com.mattintech.lchat
|
||||
|
||||
import android.app.Application
|
||||
import dagger.hilt.android.HiltAndroidApp
|
||||
|
||||
@HiltAndroidApp
|
||||
class LChatApplication : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,9 @@ import androidx.core.content.ContextCompat
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.mattintech.lchat.databinding.ActivityMainBinding
|
||||
import com.mattintech.lchat.utils.LOG_PREFIX
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
companion object {
|
||||
|
||||
23
app/src/main/java/com/mattintech/lchat/di/AppModule.kt
Normal file
23
app/src/main/java/com/mattintech/lchat/di/AppModule.kt
Normal file
@@ -0,0 +1,23 @@
|
||||
package com.mattintech.lchat.di
|
||||
|
||||
import android.content.Context
|
||||
import com.mattintech.lchat.network.WifiAwareManager
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object AppModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideWifiAwareManager(
|
||||
@ApplicationContext context: Context
|
||||
): WifiAwareManager {
|
||||
return WifiAwareManager(context)
|
||||
}
|
||||
}
|
||||
@@ -3,24 +3,19 @@ package com.mattintech.lchat.repository
|
||||
import android.content.Context
|
||||
import com.mattintech.lchat.data.Message
|
||||
import com.mattintech.lchat.network.WifiAwareManager
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
class ChatRepository private constructor(context: Context) {
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var INSTANCE: ChatRepository? = null
|
||||
|
||||
fun getInstance(context: Context): ChatRepository {
|
||||
return INSTANCE ?: synchronized(this) {
|
||||
INSTANCE ?: ChatRepository(context.applicationContext).also { INSTANCE = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
@Singleton
|
||||
class ChatRepository @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
) {
|
||||
|
||||
private val wifiAwareManager = WifiAwareManager(context)
|
||||
|
||||
@@ -140,7 +135,7 @@ class ChatRepository private constructor(context: Context) {
|
||||
|
||||
private fun startConnectionMonitoring() {
|
||||
connectionCheckJob?.cancel()
|
||||
connectionCheckJob = GlobalScope.launch {
|
||||
connectionCheckJob = CoroutineScope(Dispatchers.IO).launch {
|
||||
while (isActive) {
|
||||
delay(5000) // Check every 5 seconds
|
||||
val timeSinceLastActivity = System.currentTimeMillis() - lastActivityTime
|
||||
|
||||
@@ -6,7 +6,7 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.core.content.ContextCompat
|
||||
@@ -17,9 +17,10 @@ import com.mattintech.lchat.repository.ChatRepository
|
||||
import com.mattintech.lchat.ui.adapters.MessageAdapter
|
||||
import com.mattintech.lchat.utils.LOG_PREFIX
|
||||
import com.mattintech.lchat.viewmodel.ChatViewModel
|
||||
import com.mattintech.lchat.viewmodel.ViewModelFactory
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@AndroidEntryPoint
|
||||
class ChatFragment : Fragment() {
|
||||
|
||||
companion object {
|
||||
@@ -30,7 +31,7 @@ class ChatFragment : Fragment() {
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private val args: ChatFragmentArgs by navArgs()
|
||||
private lateinit var viewModel: ChatViewModel
|
||||
private val viewModel: ChatViewModel by viewModels()
|
||||
private lateinit var messageAdapter: MessageAdapter
|
||||
|
||||
override fun onCreateView(
|
||||
@@ -47,8 +48,6 @@ class ChatFragment : Fragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
Log.d(TAG, "onViewCreated - room: ${args.roomName}, user: ${args.userName}, isHost: ${args.isHost}")
|
||||
|
||||
val factory = ViewModelFactory(requireContext())
|
||||
viewModel = ViewModelProvider(this, factory)[ChatViewModel::class.java]
|
||||
viewModel.initialize(args.roomName, args.userName, args.isHost)
|
||||
|
||||
setupUI()
|
||||
|
||||
@@ -7,16 +7,17 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.mattintech.lchat.R
|
||||
import com.mattintech.lchat.databinding.FragmentLobbyBinding
|
||||
import com.mattintech.lchat.viewmodel.LobbyEvent
|
||||
import com.mattintech.lchat.viewmodel.LobbyState
|
||||
import com.mattintech.lchat.viewmodel.LobbyViewModel
|
||||
import com.mattintech.lchat.viewmodel.ViewModelFactory
|
||||
import com.mattintech.lchat.utils.LOG_PREFIX
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@AndroidEntryPoint
|
||||
class LobbyFragment : Fragment() {
|
||||
|
||||
companion object {
|
||||
@@ -26,7 +27,7 @@ class LobbyFragment : Fragment() {
|
||||
private var _binding: FragmentLobbyBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
|
||||
private lateinit var viewModel: LobbyViewModel
|
||||
private val viewModel: LobbyViewModel by viewModels()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@@ -42,9 +43,6 @@ class LobbyFragment : Fragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
Log.d(TAG, "onViewCreated")
|
||||
|
||||
val factory = ViewModelFactory(requireContext())
|
||||
viewModel = ViewModelProvider(this, factory)[LobbyViewModel::class.java]
|
||||
|
||||
setupUI()
|
||||
observeViewModel()
|
||||
}
|
||||
|
||||
@@ -6,11 +6,13 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.mattintech.lchat.data.Message
|
||||
import com.mattintech.lchat.repository.ChatRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.UUID
|
||||
import javax.inject.Inject
|
||||
|
||||
sealed class ChatState {
|
||||
object Connected : ChatState()
|
||||
@@ -18,7 +20,8 @@ sealed class ChatState {
|
||||
data class Error(val message: String) : ChatState()
|
||||
}
|
||||
|
||||
class ChatViewModel(
|
||||
@HiltViewModel
|
||||
class ChatViewModel @Inject constructor(
|
||||
private val chatRepository: ChatRepository
|
||||
) : ViewModel() {
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.mattintech.lchat.repository.ChatRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
sealed class LobbyState {
|
||||
object Idle : LobbyState()
|
||||
@@ -23,7 +25,8 @@ sealed class LobbyEvent {
|
||||
data class ShowError(val message: String) : LobbyEvent()
|
||||
}
|
||||
|
||||
class LobbyViewModel(
|
||||
@HiltViewModel
|
||||
class LobbyViewModel @Inject constructor(
|
||||
private val chatRepository: ChatRepository
|
||||
) : ViewModel() {
|
||||
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
package com.mattintech.lchat.viewmodel
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import com.mattintech.lchat.repository.ChatRepository
|
||||
|
||||
class ViewModelFactory(private val context: Context) : ViewModelProvider.Factory {
|
||||
|
||||
private val chatRepository by lazy { ChatRepository.getInstance(context) }
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return when {
|
||||
modelClass.isAssignableFrom(LobbyViewModel::class.java) -> {
|
||||
LobbyViewModel(chatRepository) as T
|
||||
}
|
||||
modelClass.isAssignableFrom(ChatViewModel::class.java) -> {
|
||||
ChatViewModel(chatRepository) as T
|
||||
}
|
||||
else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,5 +11,6 @@ buildscript {
|
||||
|
||||
plugins {
|
||||
id("com.android.application") version "8.9.1" apply false
|
||||
id("org.jetbrains.kotlin.android") version "1.9.0" apply false
|
||||
id("org.jetbrains.kotlin.android") version "1.9.22" apply false
|
||||
id("com.google.dagger.hilt.android") version "2.50" apply false
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
# Project-wide Gradle settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 --add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-exports=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
|
||||
android.useAndroidX=true
|
||||
android.nonTransitiveRClass=true
|
||||
android.defaults.buildfeatures.buildconfig=true
|
||||
android.nonFinalResIds=false
|
||||
android.nonFinalResIds=false
|
||||
|
||||
# Kapt configuration for better performance
|
||||
kapt.use.worker.api=true
|
||||
kapt.incremental.apt=true
|
||||
|
||||
# Hilt configuration
|
||||
dagger.hilt.android.internal.disableAndroidSuperclassValidation=true
|
||||
Reference in New Issue
Block a user