Middle
Kako organizujete interakciju između fragmenta i usluge u vašoj aplikaciji?
sobes.tech АИ
Одговор од АИ
Главни начини за интеракцију између фрагмента и сервиса су:
- Бодовани сервис (Bound Service): Фрагмент се везује за сервис и добија директан приступ јавним методама преко интерфејса
IBinder. - Покренути сервис (Started Service): Фрагмент покреће сервис слањем намера (
Intent) са подацима. За повратну информацију, сервис може слати широковасшне намере или користитиResultReceiver. - Широковасшне намере (
BroadcastReceiver): Сервис шаље широковасшне намере, а фрагмент их слуша помоћуBroadcastReceiver. - Евент Бус (нпр. GreenDao EventBus, Otto): Користи се за размену догађаја између компоненти преко централизованог управника. Сервис објављује догађаје, а фрагмент се на њих пријављује.
- LiveData: Фрагмент може посматрати објекат
LiveDataуViewModel, који, с друге стране, комуницира са сервисом (нпр. преко репозиторијума или директним позивом метода повезаног сервиса).
При избору начина узимам у обзир:
- Тип сервиса (везани или покренути).
- Потребу за двосмерном интеракцијом.
- Комплексност преносних података.
- Животни циклус фрагмента и сервиса.
- читљивост и одрживост кода.
Пример везивања фрагмента за сервис:
// Фрагмент
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
}
}
Пример слања широковасшне намере из сервиса:
// Сервис
private fun sendUpdate(data: String) {
Intent("my.app.SERVICE_UPDATE").apply {
putExtra("data", data)
}.also { intent ->
sendBroadcast(intent)
}
}
Пример прихвата широковасшне намере у фрагменту:
// Фрагмент
private val receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
"my.app.SERVICE_UPDATE" -> {
val data = intent.getStringExtra("data")
// Обрада података
}
}
}
}
override fun onResume() {
super.onResume()
IntentFilter("my.app.SERVICE_UPDATE").also { filter ->
requireContext().registerReceiver(receiver, filter)
}
}
override fun onPause() {
super.onPause()
requireContext().unregisterReceiver(receiver)
}