Middle
Como você organiza a interação entre o fragmento e o serviço na sua aplicação?
sobes.tech IA
Resposta da IA
Vou enumerar as principais formas de interação entre um fragmento e um serviço:
- Serviço vinculado (Bound Service): O fragmento liga-se ao serviço, obtendo acesso direto aos métodos públicos do serviço através da interface
IBinder. - Serviço iniciado (Started Service): O fragmento inicia o serviço enviando intenções (
Intent) com dados. Para feedback, o serviço pode enviar intenções broadcast ou usarResultReceiver. - Intenções broadcast (
BroadcastReceiver): O serviço envia intenções broadcast, e o fragmento as escuta usandoBroadcastReceiver. - Bus de eventos (por exemplo, GreenDao EventBus, Otto): São usados para trocar eventos entre componentes através de um despachante central. O serviço publica eventos, e o fragmento inscreve-se neles.
- LiveData: O fragmento pode observar um objeto
LiveDatanoViewModel, que por sua vez interage com o serviço (por exemplo, através de um repositório ou chamada direta aos métodos do serviço vinculado).
Ao escolher o método, considero:
- Tipo de serviço (vinculado ou iniciado).
- Necessidade de interação bidirecional.
- Complexidade dos dados transmitidos.
- Ciclo de vida do fragmento e do serviço.
- Legibilidade e manutenção do código.
Exemplo de ligação de um fragmento a um serviço:
// 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
}
}
Exemplo de envio de intenção broadcast do serviço:
// Serviço
private fun sendUpdate(data: String) {
Intent("my.app.SERVICE_UPDATE").apply {
putExtra("data", data)
}.also { intent ->
sendBroadcast(intent)
}
}
Exemplo de recepção de intenção broadcast no fragmento:
// 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")
// Processar dados
}
}
}
}
override fun onResume() {
super.onResume()
IntentFilter("my.app.SERVICE_UPDATE").also { filter ->
requireContext().registerReceiver(receiver, filter)
}
}
override fun onPause() {
super.onPause()
requireContext().unregisterReceiver(receiver)
}