Middle
Comment organisez-vous l'interaction entre le fragment et le service dans votre application?
sobes.tech IA
Réponse de l'IA
Je vais énumérer les principales méthodes d'interaction entre un fragment et un service:
- Service lié (Bound Service): Le fragment se lie au service, accédant directement aux méthodes publiques du service via l'interface
IBinder. - Service démarré (Started Service): Le fragment démarre le service en envoyant des intentions (
Intent) avec des données. Pour la rétroaction, le service peut envoyer des intentions broadcast ou utiliserResultReceiver. - Intentions broadcast (
BroadcastReceiver): Le service envoie des intentions broadcast, et le fragment les écoute viaBroadcastReceiver. - Bus d'événements (par exemple, GreenDao EventBus, Otto): Utilisés pour échanger des événements entre composants via un dispatcher central. Le service publie des événements, et le fragment s'y abonne.
- LiveData: Le fragment peut observer un objet
LiveDatadansViewModel, qui interagit à son tour avec le service (par exemple, via un dépôt ou un appel direct aux méthodes du service lié).
Lors du choix de la méthode, je considère:
- Type de service (lié ou démarré).
- Nécessité d'une interaction bidirectionnelle.
- Complexité des données transmises.
- Cycle de vie du fragment et du service.
- Lisibilité et maintenabilité du code.
Exemple de liaison d'un fragment à un service:
// Fragment
private lateinit var myService: MyService
private var isBound = false
private val connection = object : ServiceConnection {
override fun onServiceConnected(className: ComponentName, service: IBinder) {
val binder = service as MyService.LocalBinder
myService = binder.getService()
isBound = true
}
override fun onServiceDisconnected(arg0: ComponentName) {
isBound = false
}
}
override fun onStart() {
super.onStart()
Intent(requireContext(), MyService::class.java).also { intent ->
requireContext().bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
}
override fun onStop() {
super.onStop()
if (isBound) {
requireContext().unbindService(connection)
isBound = false
}
}
Exemple d'envoi d'une intention broadcast depuis le service:
// Service
private fun sendUpdate(data: String) {
Intent("my.app.SERVICE_UPDATE").apply {
putExtra("data", data)
}.also { intent ->
sendBroadcast(intent)
}
}
Exemple de réception d'une intention broadcast dans un fragment:
// Fragment
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
"my.app.SERVICE_UPDATE" -> {
val data = intent.getStringExtra("data")
// Traiter les données
}
}
}
}
override fun onResume() {
super.onResume()
IntentFilter("my.app.SERVICE_UPDATE").also { filter ->
requireContext().registerReceiver(receiver, filter)
}
}
override fun onPause() {
super.onPause()
requireContext().unregisterReceiver(receiver)
}