android開發:BroadcastReceiver注意事項

開始之前咱們先來理解這句話:
一個包含活躍組件的進程會被保護起來不被殺死。但是一個僅僅包含非活躍組件的進程,在系統內存不足時可能隨時被系統殺死。android組件就包含了四大組件,組件還在執行它的生命週期時我們可以認爲它是活躍的,當生命週期結束後可以認爲它不是活躍的,需要注意的是生命週期結束後不代表對象會立馬被銷燬,只是說在生命週期結束後的隨機某一時刻對象可能被銷燬。

就拿BroadcastReceiver來說,不管是靜態註冊還是動態註冊,在註冊的時候該對象會註冊到AMS中,當我們未發送廣播時BroadcastReceiver是屬於不活躍的,但是AMS持有它的引用,所以BroadcastReceiver對象處於在一種不活躍,但也不會被回收的狀態。

BroadcastReceiver注意事項:
1.動態註冊時應該在Activity生命週期結束時進行註銷,以仿內存泄漏。因爲BroadcastReceiver動態註冊時實際上是通過AMS相互持有強引用的,AMS持有廣播的引用,BroadcastReceiver對象又持有activity的引用。

2.BroadcastReceiveronReceive()方法是在主線程運行的,不能持行耗時操作,超過十秒報ANR異常。如果要進行耗時操作我們可以開啓線程。但是這樣子也不完全是安全的,因爲如果我們在onReceive()中開啓線程執行耗時操作,當onReceive()結束後BroadcastReceiver生命週期結束變成非活躍狀態。從文章第一句話來看:我們假設當BroadcastReceiver生命週期結束後整個進程所有的組件都是處於非活躍狀態,內存不足則進程被殺死,這樣子我們的子線程就完成不了我們的任務(例如我們任務就是提交一些重要的數據到後臺)。解決辦法就是開啓一個IntentService執行耗時操作,這時候系統會認爲該進程擁有活躍的組件,則不會被殺死。

感覺還是很抽象,舉個例子:
假如說我們現在在Activity中發送一個廣播,然後在BroadcastReceiveronReceive()方法中開啓子線程上傳一些圖片數據。Activity發送廣播後就立馬關閉了,Activity變成了非活躍狀態,然後BroadcastReceiver開啓子線程後onReceive()方法執行結束,也變成了非活躍狀態。此時我們進程可以看成所有的組件都是處於非活躍狀態,恰好此時系統內存不足,我們的進程被殺死,而我們的線程同樣也會被殺死,我們的異步任務則失敗。而如果我們是在onReceive()開啓一個IntentService執行任務,即時ActivityBroadcastReceiver都已經結束生命週期,IntentService還在運行,系統則判斷進程擁有活躍組件,進程就會被保護起來不被殺死。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章