Sobes.tech
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 IBinder interfé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 vagy ResultReceiver-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 a BroadcastReceiver segí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 LiveData objektumot a ViewModel-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)
}