Middle
Ako organizujete interakciu medzi fragmentom a službou vo vašej aplikácii?
sobes.tech AI
Odpoveď od AI
Hlavné spôsoby interakcie medzi fragmentom a službou sú:
- Viazaná služba (Bound Service): Fragment sa viaže na službu a získava priamy prístup k verejným metódam cez rozhranie
IBinder. - Spustená služba (Started Service): Fragment spúšťa službu odoslaním zámerov (
Intent) s údajmi. Na spätnú väzbu môže služba posielať vysielacie závery alebo používaťResultReceiver. - Vysielacie závery (
BroadcastReceiver): Služba odosiela vysielacie závery, ktoré fragment počúva pomocouBroadcastReceiver. - Esemény Bus (napríklad GreenDao EventBus, Otto): Používa sa na výmenu udalostí medzi komponentami cez centrálny správca. Služba publikuje udalosti a fragment sa na ne prihlasuje.
- LiveData: Fragment môže sledovať objekt
LiveDatavViewModel, ktorý na oplátku komunikuje so službou (napríklad cez repozitár alebo priamy volanie metód pripojenej služby).
Pri výbere spôsobu zohľadňujem:
- Typ služby (viazaná alebo spustená).
- Potrebu obojsmernej komunikácie.
- Složitost prenosu dát.
- Životný cyklus fragmentu a služby.
- Čitateľnosť a udržiavateľnosť kódu.
Príklad viazania fragmentu ku službe:
// 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
}
}
Príklad odoslania vysielacieho zámeru zo služby:
// Služba
private fun sendUpdate(data: String) {
Intent("my.app.SERVICE_UPDATE").apply {
putExtra("data", data)
}.also { intent ->
sendBroadcast(intent)
}
}
Príklad prijatia vysielacieho zámeru vo fragmente:
// 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")
// Spracovanie dát
}
}
}
}
override fun onResume() {
super.onResume()
IntentFilter("my.app.SERVICE_UPDATE").also { filter ->
requireContext().registerReceiver(receiver, filter)
}
}
override fun onPause() {
super.onPause()
requireContext().unregisterReceiver(receiver)
}