Sobes.tech
Middle+

Jakie nieoczekiwane problemy mogą wystąpić podczas pracy z korutynami w Androidzie?

sobes.tech AI

Odpowiedź od AI

  • Nieoczekiwane anulowanie: Korutyna może zostać niejawnie anulowana, na przykład podczas zmiany konfiguracji urządzenia lub zamknięcia Activity/Fragment, jeśli kontekst cyklu życia nie jest starannie zarządzany. Może to prowadzić do wycieków pamięci lub nieukończonych operacji.
  • Problemy z kontekstem (propagacja kontekstu): Przesyłanie kontekstu korutyny między warstwami aplikacji (UI, ViewModel, Repository) wymaga uwagi. Nieprawidłowe użycie kontekstu może powodować zawieszanie się UI lub blokadę wątków.
  • Wyciek zasobów przy nieobsłużonych wyjątkach: Nieobsłużone wyjątki w korutynach potomnych mogą niejawnie anulować rodzica, ale zasoby przydzielone wewnątrz potomka mogą nie zostać zwolnione.
  • "Zimne" strumienie (Flow) i zarządzanie cyklem życia: Flow jest z natury leniwe i wymaga aktywnego zbierania danych. Jeśli zbieranie nie jest odpowiednio zarządzane (np. za pomocą flowWithLifecycle lub collectLatest), można uzyskać niepożądane zachowanie przy zmianach stanu UI lub cyklu życia.
  • Blokujące wywołania: Włączenie blokujących wywołań (np. operacji sieciowych lub plikowych) w korutynie wykonywanej na głównym dispatcherze (Dispatchers.Main) spowoduje ANR.
// Przykład potencjalnego problemu z anulowaniem korutyny przy zmianie konfiguracji
class MyViewModel : ViewModel() {
    fun loadData() {
        viewModelScope.launch {
            // Długa operacja
            delay(5000)
            // Jeśli Activity zostanie ponownie utworzona podczas delay, ta linijka może nie zostać wykonana
            println("Dane załadowane")
        }
    }
}

// Przykład blokującego wywołania na głównym dispatcherze
import kotlinx.coroutines.*

fun performBlockingOperation() {
    runBlocking { // Nie używać w wątku UI!
        delay(1000) // Blokuje wątek
    }
}

// Powinno wyglądać tak:
fun performNonBlockingOperation() {
    CoroutineScope(Dispatchers.Default).launch {
        delay(1000) // Nie blokuje głównego wątku
    }
}