Introduce Hilt dependency injection

Uses Hilt to get the database initialization off of the
main thread.

The initial introduction always has a disproportionate
fan-out of boilerplate. In this case, all entry points which
were using UIViewModel needed to be annotated in order to let
the code gen know that they needed to support it.

The PacketRepository is injected into things via the main
thread (e.g., the MeshService) but due to the lazy declaration,
the database isn't hydrated until the DAO is access while on an
IO thread.
This commit is contained in:
Mike Cumings 2022-02-08 13:50:21 -08:00
parent 1f177dc63e
commit 654a32c01c
18 changed files with 131 additions and 66 deletions

View file

@ -22,7 +22,6 @@ import com.geeksville.mesh.*
import com.geeksville.mesh.MeshProtos.MeshPacket
import com.geeksville.mesh.MeshProtos.ToRadio
import com.geeksville.mesh.android.hasBackgroundPermission
import com.geeksville.mesh.database.MeshtasticDatabase
import com.geeksville.mesh.database.PacketRepository
import com.geeksville.mesh.database.entity.Packet
import com.geeksville.mesh.model.DeviceVersion
@ -36,9 +35,12 @@ import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.LocationSettingsRequest
import com.google.protobuf.ByteString
import com.google.protobuf.InvalidProtocolBufferException
import dagger.Lazy
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.*
import kotlinx.serialization.json.Json
import java.util.*
import javax.inject.Inject
import kotlin.math.absoluteValue
import kotlin.math.max
@ -49,7 +51,10 @@ import kotlin.math.max
* Note: this service will go away once all clients are unbound from it.
* Warning: do not override toString, it causes infinite recursion on some androids (because contextWrapper.getResources calls to string
*/
@AndroidEntryPoint
class MeshService : Service(), Logging {
@Inject
lateinit var packetRepository: Lazy<PacketRepository>
companion object : Logging {
@ -119,9 +124,6 @@ class MeshService : Service(), Logging {
private val serviceScope = CoroutineScope(Dispatchers.IO + serviceJob)
private var connectionState = ConnectionState.DISCONNECTED
/// A database of received packets - used only for debug log
private var packetRepo: PacketRepository? = null
private var fusedLocationClient: FusedLocationProviderClient? = null
// If we've ever read a valid region code from our device it will be here
@ -326,9 +328,6 @@ class MeshService : Service(), Logging {
info("Creating mesh service")
val packetsDao = MeshtasticDatabase.getDatabase(applicationContext).packetDao()
packetRepo = PacketRepository(packetsDao)
// Switch to the IO thread
serviceScope.handledLaunch {
loadSettings() // Load our last known node DB
@ -994,7 +993,7 @@ class MeshService : Service(), Logging {
serviceScope.handledLaunch {
// Do not log, because might contain PII
// info("insert: ${packetToSave.message_type} = ${packetToSave.raw_message.toOneLineString()}")
packetRepo!!.insert(packetToSave)
packetRepository.get().insert(packetToSave)
}
}