Sobes.tech
Middle

Kuidas korraldate teie rakenduses fragmendi ja teenuse vahelist suhtlust?

sobes.tech AI

Vastus AI-lt

Peamised viisid, kuidas fragment ja teenus omavahel suhtlevad, on järgmised:

  • Seotud teenus (Bound Service): Fragment ühendub teenusega ja saab otse juurde pääseda avalikele meetoditele IBinder liidese kaudu.
  • Algatatud teenus (Started Service): Fragment käivitab teenuse, saates Intent-i koos andmetega. Tagasiside saamiseks võib teenus saata levitatavaid Intent-e või kasutada ResultReceiver-it.
  • Levitatavad Intent-id (BroadcastReceiver): Teenus saadab levitatavaid Intent-e, mida fragment kuulab BroadcastReceiver-i kaudu.
  • Sündmuste buss (näiteks GreenDao EventBus, Otto): Kasutatakse sündmuste vahetamiseks komponentide vahel keskse juhtimissüsteemi kaudu. Teenus avaldab sündmusi, millele fragment registreerub.
  • LiveData: Fragment võib jälgida LiveData objekti ViewModel-is, mis omakorda suhtleb teenusega (näiteks läbi repozitori või otsemeetodite väljakutsega).

Valiku ajal arvestan:

  • Teenuse tüüpi (seotud või algatatud).
  • Kahepoolse suhtluse vajadust.
  • Edastatavate andmete keerukust.
  • Fragmenti ja teenuse elutsüklit.
  • Koodi loetavust ja hooldatavust.

Näide fragmenti sidumisest teenusega:

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

Näide levitatava Intent-i saatmisest teenusest:

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

Näide levitatava Intent-i vastuvõtmisest fragmentis:

// 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")
                // Andmete töötlemine
            }
        }
    }
}

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

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