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 — 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:
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).
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:
När onDestroy INTE anropas:
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 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).
| Komponent | Förstöringsmetoder | Ordning | ViewModel överlever |
|---|---|---|---|
| Activity | onDestroy | onPause → onStop → onDestroy | Nej (endast om ViewModelStore inte sparas) |
| Fragment | onDestroyView, onDestroy, onDetach | onPause → onStop → onDestroyView → onDestroy → onDetach | Ja, 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.
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:
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.
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:
Vid finish() (användaren tryckte på "Tillbaka"):
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.
Visar korrekt hantering av lifecycleScope i Activity: coroutinen startas för att övervaka nätverksstatus och avbryts i onDestroy.
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.
Fragment rensar korrekt referenser till View i onDestroyView, vilket förhindrar minnesläckor orsakade av closures.
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.
Användning av isFinishing() gör det möjligt att skilja på om Activity avslutas på användarens kommando eller för återskapande.
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
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.
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.
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.
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().
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
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.
Läs också