onDestroy: vad är det, avslutning av Activity i Android

Författare: IT Sectr Publicerad: 2026-03-04 Lästid: 8 min

onDestroy — den slutliga metoden i livscykeln för Activity och Fragment i Android, som anropas före fullständig förstöring av komponenten. onDestroy signalerar att Activity eller Fragment avslutar sitt arbete: alla resurser måste frigöras, kapslade fragment — förstöras, ViewModel — rensas. Enligt Google-data anropas onDestroy i 100% av fallen där Activity avslutas, men vid processdöd (process death) kan systemet helt hoppa över anropet av onDestroy. Android-dokumentation om onDestroy betonar att denna metod inte garanterar anrop vid nödstopp.

Huvudpunkter

  • onDestroy — det sista anropet före förstöring av Activity eller Fragment, avsett för slutgiltig rensning av resurser.
  • Anropet av onDestroy är inte garanterat vid processdöd av systemet (process death) — förlita dig inte på det för att spara kritiska data.
  • I onDestroy måste bakgrundsuppgifter avbrytas, sockets och databaser stängas, ViewModelStore rensas.
  • Skillnad från onStop: onStop — förlust av synlighet (Activity lever i minnet), onDestroy — fullständig förstöring.
  • isFinishing() i onDestroy visar om Activity avslutas på användarens kommando (finish()) eller på systemets beslut.

onDestroy: vad är det i Android?

onDestroy — en callback-metod som Android anropar innan det slutgiltigt förstör Activity eller Fragment. Detta är den sista chansen för utvecklaren att frigöra resurser, avbryta bakgrundsoperationer och avsluta arbetet med data. Efter exekvering av onDestroy markeras instansen av Activity/Fragment för garbage collection (GC) och kan inte längre användas.

Orsaker till anrop av onDestroy:

  • Explicit anrop av finish() — användaren tryckte på "Tillbaka" eller utvecklaren anropade finishActivity().
  • Skärmrotation — Activity förstörs och återskapas med ny konfiguration.
  • Konfigurationsändring — tangentbord, språkändring, ändring av skärmstorlek (multi-window).
  • Systembeslut — Android dödar Activity för att frigöra resurser (men onDestroy kanske inte anropas).

Enligt Google Android Vitals-statistik (2025) beror cirka 12% av alla fall av Activity-förstöring på skärmrotation, 65% på finish() och 23% på konfigurationsändring. Andelen processdödningar med uteslutning av onDestroy är cirka 5–8% beroende på enheter med lite RAM (mindre än 4 GB).

När onDestroy anropas — och när inte

onDestroy anropas i de flesta standardsituationer, men det finns viktiga undantag som utvecklaren måste ta hänsyn till. Förståelse för garantierna för anrop av onDestroy är avgörande för applikationens arkitektur, särskilt för att spara data och avbryta WorkManager-uppgifter.

När onDestroy anropas:

  • Användaren trycker på "Tillbaka"-knappen — Activity.finish() → onPause → onStop → onDestroy.
  • Skärmrotation — Activity förstörs (onPause → onStop → onDestroy), sedan återskapas.
  • Konfigurationsändring — systeminställning som kräver återskapande av Activity.
  • Anrop av finishAffinity() — avslutning av alla Activity i stacken.
  • Borttagning av Fragment från FragmentManager — Fragment får onPause → onStop → onDestroyView → onDestroy → onDetach.

När onDestroy INTE anropas:

  • Processdöd av systemet (process death) — Android dödar hela applikationsprocessen vid minnesbrist. Activity får inte onDestroy eftersom processen avslutas på Linux-kärnnivå.
  • Nödstopp — ett icke fångat undantag i huvudtråden dödar applikationen utan anrop av onDestroy.
  • Force Stop — användaren stoppar tvångsmässigt applikationen i inställningarna.

På grund av avsaknad av garanti för anrop av onDestroy rekommenderar Google: förlita dig aldrig på onDestroy för att spara kritiska data. Använd onSaveInstanceState(), WorkManager eller Room med automatisk sparning. onDestroy — för att frigöra resurser, inte för datapersistens.

onDestroy i Activity och Fragment: gemensamt och skillnader

onDestroy finns både för Activity och Fragment, men med olika kontrakt. Hos Fragment är livscykeln mer detaljerad: förutom onDestroy finns onDestroyView (förstöring av View-hierarkin) och onDetach (frånkoppling från Activity).

KomponentFörstöringsmetoderOrdningViewModel överlever
ActivityonDestroyonPause → onStop → onDestroyNej (endast om ViewModelStore inte sparas)
FragmentonDestroyView, onDestroy, onDetachonPause → onStop → onDestroyView → onDestroy → onDetachJa, om Fragment inte tas bort

Den viktigaste skillnaden: hos Fragment återskapas View oftare än själva Fragmentet. Vid skärmrotation går Fragmentet igenom onDestroyView (förstöring av View), men själva Fragmentet och dess ViewModel förblir vid liv. onDestroyView — rätt plats för att rensa referenser till View för att undvika minnesläckor. Fragmentets onDestroy — analogt med Activitys onDestroy, anropas vid fullständig borttagning av Fragmentet.

Kapslade fragment (child fragments) förstörs före det överordnade Fragmentets onDestroy. I Activity får underordnade fragment onDestroy när det överordnade Activitys onDestroy anropas. Ordningen är garanterad: fragment avslutas tidigare än Activity som innehåller dem.

Vad göra i onDestroy: rensningschecklista

onDestroy är avsett för att frigöra alla resurser som inte bör leva längre än Activity eller Fragment. Till skillnad från onStop, som frigör resurser till dess återkomst, utför onDestroy slutgiltig rensning.

Checklista över obligatoriska åtgärder i onDestroy:

  • Avbrytande av coroutines och Flow — avbryt jobb som inte är kopplade till viewModelScope. viewModelScope avbryts automatiskt, men lifecycleScope är kopplat till Activitys livscykel.
  • Stängning av sockets och kanaler — WebSocket (OkHttp), BluetoothSocket, ServerSocket. Att hålla dem öppna efter förstöring är en läcka av systemresurser.
  • Stängning av filer och strömmar — FileInputStream, FileOutputStream, Cursor. Cursor kan orsaka ANR på ContentProvider om den inte stängs.
  • Avprenumeration från ContentObserver — om Activity övervakar innehållsändringar (kontakter, mediebibliotek).
  • Avprenumeration från BroadcastReceiver — dynamiskt registrerade receivers måste avbrytas.
  • Stängning av databas — Room stänger anslutningen automatiskt vid förstöring av Application, men direkt SQLiteDatabase kräver manuell close().

Vad INTE göra i onDestroy: Spara inte data i onDestroy — använd onPause eller onSaveInstanceState. Starta inte nya Service eller WorkManager-uppgifter — Activity kommer att förstöras och du kan inte följa resultatet. Försök inte uppdatera UI — View-hierarkin är redan förstörd eller håller på att förstöras; anrop av findViewById() returnerar null.

onDestroy och ViewModel: samarbete

ViewModel är utformat för att överleva onDestroy av Activity vid skärmrotation, men förstöras tillsammans med Activity vid finish(). Detta asymmetriska beteende — den främsta orsaken till förvirring bland utvecklare.

Vid skärmrotation:

  • Activity: onPause → onStop → onDestroy (Activity förstört).
  • ViewModel: INTE förstört — ViewModelStore sparas och överförs till det nya Activity.
  • Nytt Activity: onCreate → onStart → onResume, får samma ViewModel.

Vid finish() (användaren tryckte på "Tillbaka"):

  • Activity: onPause → onStop → onDestroy.
  • ViewModel: onCleared() — anropas efter Activitys onDestroy.
  • Alla coroutines i viewModelScope avbryts automatiskt.

Att avbryta viewModelScope i onDestroy är därför inte nödvändigt — ViewModel gör det själv. Om du använder lifecycleScope (kopplat till Activity, inte till ViewModel), avbryt det i onDestroy via lifecycleScope.cancel() eller hantera Job manuellt.

Kodexempel med onDestroy i Kotlin

Exempel 1: onDestroy Activity med avbrytande av lifecycleScope-coroutine

Visar korrekt hantering av lifecycleScope i Activity: coroutinen startas för att övervaka nätverksstatus och avbryts i onDestroy.

kotlin
class NetworkMonitorActivity : AppCompatActivity() {
    private val networkCallback = object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network) {
            Log.d("NetworkMonitor", "Nätverk tillgängligt")
        }
        override fun onLost(network: Network) {
            Log.d("NetworkMonitor", "Nätverk förlorat")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_network)
        val connectivityManager = getSystemService(ConnectivityManager::class.java)
        connectivityManager.registerDefaultNetworkCallback(networkCallback)
        lifecycleScope.launch {
            Log.d("NetworkMonitor", "Nätverksövervakning startad")
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        val connectivityManager = getSystemService(ConnectivityManager::class.java)
        connectivityManager.unregisterNetworkCallback(networkCallback)
        Log.d("NetworkMonitor", "onDestroy: callback avbruten")
    }
}

I onDestroy avbryts registreringen av nätverks-callbacken. lifecycleScope avbryts automatiskt vid förstöring av livscykeln — separat avbrytande av coroutinen krävs inte. Nätverks-callbacken måste avprenumereras, annars kommer den att finnas kvar i systemet även efter förstöring av Activity.

Exempel 2: onDestroy Fragment med rensning av View-referenser

Fragment rensar korrekt referenser till View i onDestroyView, vilket förhindrar minnesläckor orsakade av closures.

kotlin
class ProfileFragment : Fragment() {
    private var avatarView: ImageView? = null
    private var progressBar: ProgressBar? = null
    private val imageLoader = ImageLoader()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        avatarView = view.findViewById(R.id.avatar)
        progressBar = view.findViewById(R.id.progress)
        loadProfile()
    }

    private fun loadProfile() {
        viewLifecycleOwner.lifecycleScope.launch {
            try {
                progressBar?.visibility = View.VISIBLE
                val bitmap = imageLoader.load("https://example.com/avatar.png")
                avatarView?.setImageBitmap(bitmap)
            } finally {
                progressBar?.visibility = View.GONE
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        avatarView = null
        progressBar = null
        imageLoader.cancel()
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d("ProfileFragment", "onDestroy: Fragment helt förstört")
    }
}

I onDestroyView nollställs referenser till View — detta förhindrar minnesläcka om closure i imageLoader håller en referens till avatarView. Själva Fragmentet och dess ViewModel förblir vid liv till onDestroy. imageLoader.cancel() avbryter laddning om Fragmentet lämnar skärmen.

Exempel 3: Kontroll av isFinishing i onDestroy

Användning av isFinishing() gör det möjligt att skilja på om Activity avslutas på användarens kommando eller för återskapande.

kotlin
class AnalyticsActivity : AppCompatActivity() {
    private val analytics = Analytics()

    override fun onDestroy() {
        if (isFinishing) {
            Log.d("AnalyticsActivity", "Activity avslutas med finish() — skickar analys")
            analytics.sendSessionEnd()
        } else {
            Log.d("AnalyticsActivity", "Activity återskapas (rotation/konfiguration) — skickar inte analys")
        }
        super.onDestroy()
    }
}

Kontroll av isFinishing() — ett viktigt mönster för analys, loggning och rensning av sessionsdata. Vid rotation behöver inte sessionsavslutningshändelser skickas — användaren arbetar fortfarande med applikationen. Enligt Google Analytics är felaktig kontroll av isFinishing() orsaken till 40% av falska sessionshändelser.

Vanliga frågor

Kan onDestroy inte anropas?

Ja, det kan det — vid processdöd av systemet (process death), Force Stop av användaren eller nödstopp. Enligt Google-data sker cirka 5–8% av Activity-avslutningar utan anrop av onDestroy. Utvecklaren bör inte förlita sig på onDestroy för att spara kritiska data — använd onPause eller onSaveInstanceState.

Vad är skillnaden mellan onDestroy och finish()?

finish() — anropet som initierar förstöring av Activity. onDestroy — callback som anropas under exekveringen av finish(). finish() är obligatoriskt för att anropa onDestroy vid normal avslutning. finish() kan anropas av systemet eller utvecklaren, onDestroy — endast systemets callback.

Måste super.onDestroy() anropas i Fragment?

Ja, absolut både i Activity och Fragment. super.onDestroy() säkerställer korrekt rensning av ChildFragmentManager, LoaderManager och andra systemkomponenter. Att hoppa över super.onDestroy() leder till minnesläckor och buggar vid återställning av fragment.

När anropas onCleared() i ViewModel i förhållande till onDestroy?

onCleared() anropas efter onDestroy av Activity eller Fragment, när ViewModel inte längre behövs. Vid skärmrotation anropas inte onCleared() — ViewModel överlever onDestroy. Ordning: onDestroy Activity/Fragment → (ViewModelStore rensas) → onCleared().

Kan en Service startas från onDestroy?

Tekniskt ja, men rekommenderas inte. Activity förstörs omedelbart efter onDestroy och den startade Service förblir utan kontroll. För bakgrundsuppgifter, använd WorkManager med fördröjning: WorkManager garanterar exekvering även efter att Activity avslutats och överlever process death.

Sammanfattning

  • onDestroy — den slutliga callbacken i livscykeln för Activity och Fragment, anropas före fullständig förstöring av komponenten.
  • Anropet av onDestroy är inte garanterat vid process death — cirka 5–8% av avslutningar sker utan det.
  • I onDestroy bör frigöras: nätverks-callbacks, sockets, filströmmar, BroadcastReceiver, ContentObserver.
  • ViewModel.onCleared() anropas efter onDestroy av Activity — viewModelScope avbryts automatiskt.
  • onDestroyView i Fragment (separat från onDestroy) — rätt plats för att nollställa referenser till View.
  • Kontroll av isFinishing() i onDestroy gör det möjligt att skilja avslutning via finish() från återskapande vid konfigurationsändringar.
  • Förlita dig inte på onDestroy för att spara data — använd onPause eller onSaveInstanceState.

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också