前提條件:此處我主要討論兩種廣播在代碼中動態注冊時的一些細節問題。
正常情況下,廣播通常都是執行一次注冊代碼,就會觸發各接收器接收一次,無論是在onCreate里注冊還是onResume里注冊:若在onCreate里注冊,一般我們在onDestroy中進行注銷;若在onResume里注冊,一般我們在onPause里進行注銷。
sendBroadcast為普通廣播,若是動態注冊的話:
只有先注冊再發送廣播,發送出來的intent才可以被接收器接收到,并執行接收器對象中的onReceive方法;若廣播先發出來,再注冊,廣播先前發出來的intent是無法被接收器接收到的,也無法執行其onReceive方法。
sendStickyBroadcast廣播,若是動態注冊的話:
與sendBroadcast不同的是,sendStickyBroadcast無論是先注冊再發送還是先發送再注冊,發送出來的intent均可以被接收器接收到。當然你在使用sendStickyBroadcast廣播時,首先需要在manifest.xml文件中配置此類型廣播權限<uses-permissionandroid:name="android.permission.BROADCAST_STICKY"/>。
具體說明如下:
1、 在注冊之前廣播就發送出來了的intent會被緩存在內存中,待廣播一旦注冊該intent就會被接收器接收,并執行onReceive方法;
2、 若注冊之后廣播發送出來,觸發接收器接收intent,接收器首先會去檢索系統緩存中是否存在intent對象,若系統中不存在緩存的intent,廣播intent發送過來時,系統會先將其保留到緩存中,接收器會接收當前的intent;若系統中已存在緩存的intent,則接收器首先會接收緩存中保存的intent,再接著接收當前發送過來的intent,即此時會執行兩次廣播接收器onReceive方法,為避免重復執行廣播接收器,可以在onReceive方法中調用removeStickyBroadcast(intent)方法,將緩存中的intent移除。這樣下次接收器檢索不到緩存中的intent,就直接接收廣播發送過來的intent;
3、 若當前廣播為sendStickyBroadcast,然后代碼中改為普通廣播,這時緩存中保存的intent依然會被接收器接收,再接收當前發送過來的intent,效果和sendStickyBroadcast一樣,哪怕清除應用本身的數據也還是如此,緩存中的intent對象依然存在。另一種現象是此時若先發送普通廣播,再注冊,此時普通廣播的接收器雖然接收不到發送過來的廣播,但可以接收到先前使用sendStickyBroadcast廣播時緩存中的intent,當然這種奇異現象只會出現在調試代碼的情況下,是不會出現在應用本身的執行過程中。該緩存中的intent對象只有在重啟手機的情況下才會被銷毀或者當內存不足,系統自動銷毀。
4、 緩存中的intent對象對應不同的action,若通過sendStickyBroadcast發送廣播設置不同的action值,將會在系統中分別對不同的action緩存不同的intent對象;即,若設置StickyBroadcast的action為A,則發送廣播后會在系統中緩存一個對應的intentA對象,若設置StickyBroadcast的action為B,則發送廣播后會在系統中緩存一個對應的intentB對象;這些緩存中的intent對象只有在重啟手機的情況下才會被銷毀或者當內存不足,系統自動銷毀。
?