Sobes.tech
Middle

Kaip organizuojate sąveiką tarp fragmento ir paslaugos jūsų programoje?

sobes.tech AI

Atsakymas iš AI

Pagrindiniai būdai, kaip sąveikauja fragmentas ir paslauga, yra šie:

  • Susietoji paslauga (Bound Service): Fragmentas prisijungia prie paslaugos ir gauna tiesioginę prieigą prie viešųjų metodų per IBinder sąsają.
  • Pradėta paslauga (Started Service): Fragmentas paleidžia paslaugą, siunčiant Intent su duomenimis. Grįžtamojo ryšio atveju paslauga gali siųsti transliuojamus Intent arba naudoti ResultReceiver.
  • Transliuojami Intent (BroadcastReceiver): Paslauga siunčia transliuojamus Intent, kuriuos fragmentas klausosi naudodamas BroadcastReceiver.
  • Renginys autobusui (Event Bus, pvz., GreenDao EventBus, Otto): Naudojamas įvykių keitimui tarp komponentų per centrinį valdytoją. Paslauga skelbia įvykius, o fragmentas į juos prenumeruoja.
  • LiveData: Fragmentas gali stebėti LiveData objektą ViewModel ir, savo ruožtu, sąveikauti su paslauga (pvz., per saugyklą arba tiesioginį metodų iškvietimą).

Renkantis būdą, atsižvelgiu į:

  • Paslaugos tipą (susietą ar pradėtą).
  • Dviejų krypčių sąveikos poreikį.
  • Perduodamų duomenų sudėtingumą.
  • Fragmento ir paslaugos gyvavimo ciklą.
  • Kodo skaitomumą ir palaikymą.

Pavyzdys, kaip susieti fragmentą su paslauga:

// Fragmentas
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
    }
}

Pavyzdys, kaip siųsti transliuojamą Intent iš paslaugos:

// Paslauga
private fun sendUpdate(data: String) {
    Intent("my.app.SERVICE_UPDATE").apply {
        putExtra("data", data)
    }.also { intent ->
        sendBroadcast(intent)
    }
}

Pavyzdys, kaip priimti transliuojamą Intent fragmento:

// Fragmentas
private val receiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        when (intent?.action) {
            "my.app.SERVICE_UPDATE" -> {
                val data = intent.getStringExtra("data")
                // Duomenų apdorojimas
            }
        }
    }
}

override fun onResume() {
    super.onResume()
    IntentFilter("my.app.SERVICE_UPDATE").also { filter ->
        requireContext().registerReceiver(receiver, filter)
    }
}

override fun onPause() {
    super.onPause()
    requireContext().unregisterReceiver(receiver)
}