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

@ -6,7 +6,6 @@ import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import com.geeksville.android.Logging
import com.geeksville.android.hideKeyboard
import com.geeksville.mesh.R
@ -16,7 +15,9 @@ import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.service.MeshService
import com.geeksville.util.exceptionToSnackbar
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class AdvancedSettingsFragment : ScreenFragment("Advanced Settings"), Logging {
private val MAX_INT_DEVICE = 0xFFFFFFFF
private var _binding: AdvancedSettingsBinding? = null

View file

@ -33,6 +33,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.google.protobuf.ByteString
import com.google.zxing.integration.android.IntentIntegrator
import dagger.hilt.android.AndroidEntryPoint
import java.security.SecureRandom
@ -51,6 +52,7 @@ fun ImageView.setOpaque() {
imageAlpha = 255
}
@AndroidEntryPoint
class ChannelFragment : ScreenFragment("Channel"), Logging {
private var _binding: ChannelFragmentBinding? = null

View file

@ -6,13 +6,15 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.Observer
import androidx.lifecycle.asLiveData
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.geeksville.mesh.R
import com.geeksville.mesh.databinding.DebugFragmentBinding
import com.geeksville.mesh.model.UIViewModel
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class DebugFragment : Fragment() {
private var _binding: DebugFragmentBinding? = null
@ -48,8 +50,8 @@ class DebugFragment : Fragment() {
binding.closeButton.setOnClickListener {
parentFragmentManager.popBackStack()
}
model.allPackets.observe(viewLifecycleOwner, Observer { packets ->
model.allPackets.asLiveData().observe(viewLifecycleOwner) { packets ->
packets?.let { adapter.setPackets(it) }
})
}
}
}

View file

@ -32,8 +32,10 @@ import com.mapbox.maps.extension.style.sources.generated.GeoJsonSource
import com.mapbox.maps.plugin.animation.MapAnimationOptions
import com.mapbox.maps.plugin.animation.flyTo
import com.mapbox.maps.plugin.gestures.gestures
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class MapFragment : ScreenFragment("Map"), Logging {
private val model: UIViewModel by activityViewModels()

View file

@ -26,6 +26,7 @@ import com.geeksville.mesh.databinding.MessagesFragmentBinding
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.mesh.service.MeshService
import com.google.android.material.chip.Chip
import dagger.hilt.android.AndroidEntryPoint
import java.text.DateFormat
import java.util.*
@ -41,6 +42,7 @@ fun EditText.on(actionId: Int, func: () -> Unit) {
}
}
@AndroidEntryPoint
class MessagesFragment : ScreenFragment("Messages"), Logging {
private var _binding: MessagesFragmentBinding? = null

View file

@ -49,6 +49,7 @@ import com.google.android.gms.location.LocationSettingsRequest
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.snackbar.Snackbar
import com.hoho.android.usbserial.driver.UsbSerialDriver
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -439,6 +440,7 @@ class BTScanModel(app: Application) : AndroidViewModel(app), Logging {
}
@SuppressLint("NewApi")
@AndroidEntryPoint
class SettingsFragment : ScreenFragment("Settings"), Logging {
private var _binding: SettingsFragmentBinding? = null

View file

@ -9,7 +9,6 @@ import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.core.text.HtmlCompat
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.geeksville.android.Logging
@ -19,9 +18,11 @@ import com.geeksville.mesh.databinding.AdapterNodeLayoutBinding
import com.geeksville.mesh.databinding.NodelistFragmentBinding
import com.geeksville.mesh.model.UIViewModel
import com.geeksville.util.formatAgo
import dagger.hilt.android.AndroidEntryPoint
import java.net.URLEncoder
import kotlin.math.roundToInt
@AndroidEntryPoint
class UsersFragment : ScreenFragment("Users"), Logging {
private var _binding: NodelistFragmentBinding? = null