Middle
Hogyan szervezed meg a fragmentum és a szolgáltatás közötti interakciót az alkalmazásodban?
sobes.tech MI
Válasz az MI-től
Főbb módjai a fragmentum és a szolgáltatás közötti interakciónak a következők:
- Kötött Szolgáltatás (Bound Service): A fragmentum kötődik a szolgáltatáshoz, és közvetlen hozzáférést kap a nyilvános módszerekhez az
IBinderinterfészen keresztül. - Indított Szolgáltatás (Started Service): A fragmentum elindít egy szolgáltatást, szándékokat (
Intent) küldve adatokkal. Visszacsatolásként a szolgáltatás széles körű szándékokat küldhet vagyResultReceiver-t használhat. - Széles körű szándékok (
BroadcastReceiver): A szolgáltatás széles körű szándékokat küld, amelyeket a fragmentum aBroadcastReceiversegítségével hallgat. - Esemény Busz (pl. GreenDao EventBus, Otto): Események cseréjére szolgál a komponensek között egy központi kezelőn keresztül. A szolgáltatás közzéteszi az eseményeket, a fragmentum pedig feliratkozik rájuk.
- LiveData: A fragmentum figyelheti a
LiveDataobjektumot aViewModel-ben, amely viszont a szolgáltatással kommunikál (például egy repository vagy közvetlen hívás révén a kötött szolgáltatás módszereire).
A módszer kiválasztásánál figyelembe veszem:
- A szolgáltatás típusát (kötött vagy indított).
- A kétirányú kommunikáció szükségességét.
- Az átadott adatok összetettségét.
- A fragmentum és a szolgáltatás életciklusát.
- A kód olvashatóságát és karbantarthatóságát.
Példa a fragmentum kötésére a szolgáltatáshoz:
// 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
}
}
Példa a széles körű szándék küldésére a szolgáltatásból:
// Szolgáltatás
private fun sendUpdate(data: String) {
Intent("my.app.SERVICE_UPDATE").apply {
putExtra("data", data)
}.also { intent ->
sendBroadcast(intent)
}
}
Példa a széles körű szándék fogadására a fragmentumban:
// 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")
// Adatok feldolgozása
}
}
}
}
override fun onResume() {
super.onResume()
IntentFilter("my.app.SERVICE_UPDATE").also { filter ->
requireContext().registerReceiver(receiver, filter)
}
}
override fun onPause() {
super.onPause()
requireContext().unregisterReceiver(receiver)
}