Middle
Cum organizați interacțiunea dintre fragment și serviciu în aplicația dvs.?
sobes.tech AI
Răspuns de la AI
Voi enumera principalele moduri de interacțiune între un fragment și un serviciu:
- Serviciu legat (Bound Service): Fragmentul se leagă de serviciu, obținând acces direct la metodele publice ale serviciului prin interfața
IBinder. - Serviciu pornit (Started Service): Fragmentul pornește serviciul trimițând intenții (
Intent) cu date. Pentru feedback, serviciul poate trimite intenții broadcast sau poate folosiResultReceiver. - Intenții broadcast (
BroadcastReceiver): Serviciul trimite intenții broadcast, iar fragmentul le ascultă cu ajutorulBroadcastReceiver. - Bus de evenimente (de exemplu, GreenDao EventBus, Otto): Folosit pentru schimbul de evenimente între componente printr-un dispatcher central. Serviciul publică evenimente, iar fragmentul se abonează la ele.
- LiveData: Fragmentul poate observa un obiect
LiveDataînViewModel, care, la rândul său, interacționează cu serviciul (de exemplu, printr-un depozit sau apel direct al metodelor serviciului legat).
Când aleg metoda, iau în considerare:
- Tipul serviciului (legat sau pornit).
- Necesitatea unei interacțiuni bidirecționale.
- Complexitatea datelor transmise.
- Ciclul de viață al fragmentului și al serviciului.
- Claritatea și întreținerea codului.
Exemplu de legare a unui fragment la un serviciu:
// 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
}
}
Exemplu de trimitere a unei intenții broadcast din serviciu:
// Serviciu
private fun sendUpdate(data: String) {
Intent("my.app.SERVICE_UPDATE").apply {
putExtra("data", data)
}.also { intent ->
sendBroadcast(intent)
}
}
Exemplu de recepție a unei intenții broadcast în fragment:
// 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")
// Procesare date
}
}
}
}
override fun onResume() {
super.onResume()
IntentFilter("my.app.SERVICE_UPDATE").also { filter ->
requireContext().registerReceiver(receiver, filter)
}
}
override fun onPause() {
super.onPause()
requireContext().unregisterReceiver(receiver)
}