關於Android Broadcast 的一樁血案

2021-09-29 09:18:53 字數 2557 閱讀 5162

之前一直使用broadcast都僅僅侷限於簡單呼叫,疑惑是根據需求選擇傳送方式,亦或是看心情決定是什麼方式註冊,直到今天,發生了乙個關於廣播的血案,事情的經過是這樣:嫌疑人a傳送了乙個無序廣播,通知各位聽眾某某事情,聽眾b舉報別人聽到了,它沒聽見,a大喊冤枉,我都廣播了,並且是不分高低貴賤的無序廣播,你沒收到是你的問題,是不是你腦袋卡殼阻塞在**,b一聽急了,我幹其它事好好的,怎麼就是沒收到?看似一樁懸案就要誕生了!

ab各有理,看似毫無頭緒,a說它發了,b說它收不到,那問題只能是中間環節出了紕漏,不經納悶了,中間能出什麼紕漏?非同步的基於訊息機制的android身上,什麼都有可能。這個貌似一發一收的問題,歸根於中間環節,那就一定是哪塊阻塞了,無序廣播怎麼會阻塞?無序廣播只是說平等對待,至於它背地裡做了什麼?所以指不定就是無序廣播傳送過程中阻塞在了**?不信,b可以多等等,如果是傳送過程阻塞在**,那阻塞的地方肯定發生anr,時間到了,b自然會收到,只是時間長短問題!!!

1) a呼叫呼叫context.sendbroadcast();進入context類,發現它是個抽象類,實現位於contextimpl

2) contextimpl中的sendbroadcast()主要做了以下工作:

activitymanager.getservice().broadcastintent(

options, false, false, getuserid());

可以看到contextimpl把工作扔給ams

3) ams中的broadcastintent()主要做了以下工作:

intent, resolvedtype, resultto, resultcode, resultdata, resultextras,

callingpid, callinguid, userid);

4) ams中的broadcastintentlocked()主要做了以下工作

// figure out who all will receive this broadcast.

list receivers = null; //靜態廣播

list

registeredreceivers = null; //動態廣播

// need to resolve the intent to interested receivers...

if ((intent.getflags()&intent.flag_receiver_registered_only)

== 0)

if (intent.getcomponent() == null)

...int nr = registeredreceivers != null ? registeredreceivers.size() : 0;

if (!ordered && nr > 0)

registeredreceivers = null;

nr = 0;

}...

if ((receivers != null && receivers.size() > 0)

|| resultto != null) else

貌似從上面**中只能得到的資訊是傳送的動態廣播比靜態廣播早!!!和案情也沒什麼關係,但是可以得到如下三個資訊:

//廣播載體 broadcastrecord

//傳送動態廣播

queue.enqueueparallelbroadcastlocked(r);

queue.schedulebroadcastslocked();

// 傳送靜態廣播

queue.enqueueorderedbroadcastlocked(r);

queue.schedulebroadcastslocked();

明顯可以看到動態廣播和靜態廣播走的不同分支:

動態廣播 -> queue.enqueueparallelbroadcastlocked(r);// 直**:paralle是併發,不會阻塞

靜態廣播    -> queue.enqueueorderedbroadcastlocked(r);// 直**.ordered,序列,可能發生阻塞

之前一直認為有序、無序、粘性才會影響傳送,有序由於等客戶端響應,可能造成阻塞,現在看來註冊方式也會導致傳送廣播時走到不同分支,有可能造成阻塞!!!

案件終於真想大白!!!小小嘚瑟下,nnd!!!

初入問題,先入為主,以為a傳送的無序廣播,不有由於聽眾某某某的阻塞造成b收不到廣播!!!但忽略了一點,註冊方式其實也是有可能對廣播造成影響!!!

1)有序廣播可能由於乙個接收端的阻塞造成其它監聽者沒收到!

2)無序廣播時,靜態註冊監聽廣播是序列的,由於廣播arraylist中broadrecord的增多而導致傳送阻塞,靜態方式註冊的該廣播的接收者會都收不到廣播。動態註冊的接收者可以收到廣播

a: 傳送端序列廣播太多

b:某個接收端阻塞

動態靜態有序b

a、b無序×a

粘性×a

強列推薦:

不管傳送方式、註冊方式,盡量別用靜態註冊,接收的慢不說,還可能造成系統效能不足導致的傳送端序列廣播阻塞;

關於程式關於世界

首先,在學了1年多的軟體設計的基礎上,問下自己 程式是什麼?業務需求是什麼?程式有什麼用?什麼是演算法?什麼是資料庫?或許每個人的理解不同,會給出不同的答案。那麼自己的理解 程式是乙個讓計算機工作的流程,在程式寫好之後,計算機就會按照,程式設計師定義好流程在執行。其實很多時候,乙個程式的好壞,在於乙...

關於血液關於軟體

1 自然沉降法 將血袋垂直吊掛於4 2 冰箱內,使紅細胞自然下沉1 3d,或將血袋呈70 80 角立於冰箱,需用時,用一次性分漿器分出血漿,制得濃縮紅細胞。2 洗滌法 一般用生理鹽水反覆洗滌3 6次。經洗滌的紅細胞,除白細胞和血小板減少外,血漿蛋白也極少,紅細胞中殘存的血漿蛋白含量約為原總蛋白的1 ...

關於冷漠,關於愛情

我不知道為什麼今天又莫名其妙開始思考愛情這件事,隨之就解決了我一直無法面對冷漠這件事 被冷漠是我始終無法消化的一件事,每當遇見冷漠時,我總會覺得就像一團火把自己燒得面目全非,但對方卻毫無傷害。但我突然懂了,遇到冷漠時,體面的離開即可 在乎你的人一定會在你離開後,找到你跟你解釋為什麼 連解釋都來不及,...