開始之前咱們先來理解這句話:
一個包含活躍組件的進程會被保護起來不被殺死。但是一個僅僅包含非活躍組件的進程,在系統內存不足時可能隨時被系統殺死。android組件就包含了四大組件,組件還在執行它的生命週期時我們可以認爲它是活躍的,當生命週期結束後可以認爲它不是活躍的,需要注意的是生命週期結束後不代表對象會立馬被銷燬,只是說在生命週期結束後的隨機某一時刻對象可能被銷燬。
就拿BroadcastReceiver
來說,不管是靜態註冊還是動態註冊,在註冊的時候該對象會註冊到AMS
中,當我們未發送廣播時BroadcastReceiver
是屬於不活躍的,但是AMS
持有它的引用,所以BroadcastReceiver
對象處於在一種不活躍,但也不會被回收的狀態。
BroadcastReceiver注意事項:
1.動態註冊時應該在Activity
生命週期結束時進行註銷,以仿內存泄漏。因爲BroadcastReceiver
動態註冊時實際上是通過AMS
相互持有強引用的,AMS
持有廣播的引用,BroadcastReceiver
對象又持有activity的引用。
2.BroadcastReceiver
的onReceive()
方法是在主線程運行的,不能持行耗時操作,超過十秒報ANR
異常。如果要進行耗時操作我們可以開啓線程。但是這樣子也不完全是安全的,因爲如果我們在onReceive()
中開啓線程執行耗時操作,當onReceive()
結束後BroadcastReceiver
生命週期結束變成非活躍狀態。從文章第一句話來看:我們假設當BroadcastReceiver
生命週期結束後整個進程所有的組件都是處於非活躍狀態,內存不足則進程被殺死,這樣子我們的子線程就完成不了我們的任務(例如我們任務就是提交一些重要的數據到後臺)。解決辦法就是開啓一個IntentService
執行耗時操作,這時候系統會認爲該進程擁有活躍的組件,則不會被殺死。
感覺還是很抽象,舉個例子:
假如說我們現在在Activity
中發送一個廣播,然後在BroadcastReceiver
的onReceive()
方法中開啓子線程上傳一些圖片數據。Activity
發送廣播後就立馬關閉了,Activity
變成了非活躍狀態,然後BroadcastReceiver
開啓子線程後onReceive()
方法執行結束,也變成了非活躍狀態。此時我們進程可以看成所有的組件都是處於非活躍狀態,恰好此時系統內存不足,我們的進程被殺死,而我們的線程同樣也會被殺死,我們的異步任務則失敗。而如果我們是在onReceive()
開啓一個IntentService
執行任務,即時Activity
、BroadcastReceiver
都已經結束生命週期,IntentService
還在運行,系統則判斷進程擁有活躍組件,進程就會被保護起來不被殺死。