MediaSessionCompat::setMetadata調(diào)用時(shí)遇到的深坑

本文主要講解了一下幾個(gè)方面:

(1)bitmap.copy()發(fā)生np的原因及Config 為何為null;

(2)不同系統(tǒng)setMetadata的實(shí)現(xiàn)機(jī)制及其差異性對(duì)比;

(3)不同版本support 庫MediaSessioCompat::setMetadata實(shí)現(xiàn)差異枫疆。

一潭兽、深坑背景?

既然是深坑聚请,必然是難以發(fā)現(xiàn)(偶現(xiàn)問題),大家可能在想MediaSessionCompat::setMetadata()一個(gè)方法調(diào)用還未出現(xiàn)什么問題,正因我也是這么想拇派,所以問題發(fā)生了 拍屑。

問題現(xiàn)場 ?:在RDM問題列表中發(fā)現(xiàn)了一個(gè)np問題 (只有幾例途戒,上報(bào)機(jī)型均為小米系統(tǒng),api19)僵驰,來自bitmap.copy() 喷斋,對(duì)應(yīng)到項(xiàng)目調(diào)用處 mMediaSessionCompat.setMetadata() 如下圖所示 ,這里是專門針對(duì)小米系統(tǒng)鎖屏進(jìn)行的相關(guān)處理蒜茴。

圖1 問題現(xiàn)場
圖2 bitmap.copy np 處

一看便知 星爪,傳入的congfig為null導(dǎo)致 ,為什么config為null粉私,我們后面再講顽腾,先來看看為什么setMetadata會(huì)導(dǎo)致bitmap.copy ,帶著疑問去看看setMetadata的調(diào)用過程诺核。


二抄肖、MediaSessioCompat::setMetadata 調(diào)用過程

? ? ? 在講解MediaSessioCompat::setMetadata前,先了解一下RemoteControlClient窖杀、MediaSession等多媒體控制相關(guān)類漓摩。

? ? ? ?RemoteControlClient 主要用于鎖屏狀態(tài)控制音樂播放,鎖屏界面由系統(tǒng)提供入客,在Android 4.0 (API 14)提供管毙,目前已經(jīng)被標(biāo)記為deprecated(目前已推薦使用MediaSession)腿椎。 MediaSession? 是一個(gè)專門解決媒體播放時(shí)界面和服務(wù)通訊問題的框架,在Android 5.0才被引進(jìn)夭咬,可應(yīng)用在鎖屏啃炸、耳機(jī)線控、藍(lán)牙耳機(jī)卓舵。

? ? ? 而這里的MediaSessioCompat 是support包提供的一個(gè)兼容性類 南用,從命名就可以看出來,setMetadata方法作用主要是更新數(shù)據(jù)(包括歌曲名边器、歌手训枢、背景圖、字幕等信息)忘巧,因此對(duì)于音頻類系統(tǒng)鎖屏是相當(dāng)重要的恒界。

MediaSessioCompat::setMetadata()內(nèi)部實(shí)踐上調(diào)用的是 MediaSessionImpl::setMetadata,既然是兼容類 砚嘴,對(duì)應(yīng)的MediaSessionImpl 肯定在不同版本有著不同實(shí)現(xiàn) (api 21 作為區(qū)分節(jié)點(diǎn))十酣,如下:

圖3 MediaSessionImpl實(shí)現(xiàn)

(1)MediaSessionImplBase::setMetadata? (api <21)

? ? ? ?在MediaSessionImplBase內(nèi)部 主要進(jìn)行了兩大操作,先對(duì)metadata數(shù)據(jù)中的 bitmaps數(shù)據(jù)進(jìn)行拷貝 (發(fā)現(xiàn)bitmap相關(guān)操作了)际长,然后又對(duì)api 19 和 api 14 分別進(jìn)行了區(qū)分(后面解釋為什么會(huì)進(jìn)行區(qū)分)耸采,調(diào)用各自的setMetadata。

圖 4 MediaSessionImplBase::setMetadata? (api <21)

沒錯(cuò)工育,bitmap.copy()的np問題正是發(fā)生在這里虾宇,通過Bitmap相關(guān)api注釋知,bitmap.getConfig()可能返回為null如绸,奈何這竟然是一個(gè)系統(tǒng)bug嘱朽,迭代了這么多版本google竟未修復(fù)。

圖5 cloneMetadataIfNeeded()

這里的Config其實(shí)指的是 bitmap的類型 :可以看到確實(shí)有兩類返回的config為null

圖6 Config

? ? ? 具體什么情況為null了 怔接,我在Bitmapcreate Bitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) 實(shí)現(xiàn)中找到了蛛絲馬跡搪泳,如下圖中注釋:gif 文件會(huì)產(chǎn)出 null configs,但是對(duì)于我們項(xiàng)目來說扼脐,專輯封面采用的都不是gif格式岸军,因此對(duì)于bitmap.getConfig()返回為null還是為弄清(那位大神知道請(qǐng)告訴一下,謝謝)瓦侮。

圖7 BitmapcreateBitmap 內(nèi)部實(shí)現(xiàn)

? ? ? ?雖然這個(gè)np問題可以輕而易舉的解決艰赞,單本人不甘停留如此,還有有個(gè)疑問為什么要clone bitmap相關(guān)數(shù)據(jù)(注釋已經(jīng)說了肚吏,防止recycle)猖毫,那在什么時(shí)候會(huì)recycle 。

(2)在那里進(jìn)行recycle操作

在(1)中已經(jīng)說過须喂,MediaSessionImplBase里面會(huì)進(jìn)行兩部分操作吁断,第二部分操作是setMetadata,其內(nèi)部實(shí)現(xiàn)如下:

創(chuàng)建editor 坞生、put 數(shù)據(jù)仔役、最后apply。 ?這里分別使用了RemoteControlClient.MetadataEditor和MediaMetadataEditor (api 19 才提供)是己。

圖8 MediaSessionCompatApi19

? ? ? ? apply()才是關(guān)鍵 又兵,內(nèi)部實(shí)現(xiàn)如下:其中mOriginalArtWork就是專門用來緩存封面的bitmap ,可能考慮到鎖屏比較頻繁卒废,防止頻繁調(diào)用吧沛厨,但是bitmap.recycle() 不是在2.3.3以后就不推薦使用嗎,真不知道為何在此還要如此實(shí)現(xiàn)摔认。

圖9 RemoteControlClient::apply()

? ? ? 細(xì)心一點(diǎn)的同學(xué)可能發(fā)現(xiàn)逆皮,在這個(gè)里面竟然調(diào)用了MediaSession::setMetadata()根據(jù),前面對(duì)MediaSession(5.0 引進(jìn))介紹知参袱,在5.0以下實(shí)現(xiàn)方式肯定不一致:

圖 10 4.4.4 版本的apply()方法

另外 电谣,在高版本中又是如何處理相關(guān)問題的了,帶著這些疑問我們直接分析MediaSession::setMetadata()方法即可抹蚀。


三剿牺、MediaSession::setMetadata()

? ? ? ?在第二部分,主要講解了MediaSessioCompat::setMetadata api 21以下的調(diào)用环壤,在api >=21時(shí)晒来,其內(nèi)部調(diào)用的是 MediaSession::setMetadata(),具體如下:

圖11 MediaSession::setMetadata()

這里也是分為兩步 :更新metadata 數(shù)據(jù)郑现,執(zhí)行更新 湃崩。

相比api <21 情況,這里并未clone 封面背景bitmap 懂酱,保證了一定性能竹习。內(nèi)部使用的是scaleBitmap 最后實(shí)際調(diào)用Bitmapcreate Bitmap(Bitmap source, int x, int y, int width, int height, Matrix m, boolean filter) ,整個(gè)過程簡單明了列牺。

而對(duì)于執(zhí)行更新整陌,這里采用的IPC 方式,上面的mBinder 其實(shí)是 ISession.aidl 對(duì)象瞎领,效率相比之前的提高不少泌辫。(這里具體就不展開。)


四九默、不同版本support 庫MediaSessioCompat::setMetadata實(shí)現(xiàn)差異

? ? ? ?前面講的MediaSessioCompat 是基于support-v4-23.4.0 版本震放,可以看到MediaSessioCompat為了配合RemoteContorlClient::apply() 方法中的 bitmap.recyle() , 在setMetadta內(nèi)部對(duì)進(jìn)行了Clone。

圖12 support-v4-23.4.0 MediaSessioCompat::setMetadata()

? ? ? 而在support-v4-22.2.1 中發(fā)現(xiàn)驼修,并未對(duì)封面bitmap 進(jìn)行可能殿遂,這種情況下诈铛,發(fā)生crash是必然的,可能正因如此墨礁,google在后面的support 庫修復(fù)了這個(gè)問題幢竹。support-v4-23.4.0版本發(fā)生np ,原因前面已經(jīng)說了恩静,是因?yàn)閎itmap.getConfig()為null導(dǎo)致 (這種情況極其少焕毫,因而極難發(fā)現(xiàn))。

圖13 support-v4-22.2.1 MediaSessioCompat::setMetadata()


感慨:本文主要記錄了一次系統(tǒng)填坑經(jīng)歷 驶乾;反思邑飒,在使用系統(tǒng)API時(shí)一定要全面弄清,盡量避免進(jìn)坑级乐。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疙咸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子唇牧,更是在濱河造成了極大的恐慌罕扎,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件丐重,死亡現(xiàn)場離奇詭異腔召,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)扮惦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門臀蛛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人崖蜜,你說我怎么就攤上這事浊仆。” “怎么了豫领?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵抡柿,是天一觀的道長。 經(jīng)常有香客問我等恐,道長洲劣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任课蔬,我火速辦了婚禮囱稽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘二跋。我一直安慰自己战惊,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布扎即。 她就那樣靜靜地躺著吞获,像睡著了一般况凉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上衫哥,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天茎刚,我揣著相機(jī)與錄音,去河邊找鬼撤逢。 笑死,一個(gè)胖子當(dāng)著我的面吹牛粮坞,可吹牛的內(nèi)容都是我干的蚊荣。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼莫杈,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼互例!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起筝闹,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤媳叨,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后关顷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糊秆,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年议双,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了痘番。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡平痰,死狀恐怖汞舱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情宗雇,我是刑警寧澤昂芜,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站赔蒲,受9級(jí)特大地震影響泌神,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜嘹履,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一腻扇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧砾嫉,春花似錦幼苛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽墙杯。三九已至,卻和暖如春括荡,著一層夾襖步出監(jiān)牢的瞬間高镐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來泰國打工畸冲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫉髓,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓邑闲,卻偏偏與公主長得像算行,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子苫耸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,846評(píng)論 25 707
  • EnglishVersion ->_->:https://github.com/jiang111/awesome-...
    聶順閱讀 1,223評(píng)論 0 4
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理州邢,服務(wù)發(fā)現(xiàn),斷路器褪子,智...
    卡卡羅2017閱讀 134,637評(píng)論 18 139
  • 10月10日星期二晴 今天再學(xué)校一天量淌,今天的作業(yè)做的挺快的給他個(gè)小小的獎(jiǎng)勵(lì)。
    梁朋懷閱讀 139評(píng)論 0 0
  • 1 最近在朋友圈發(fā)了一段話: “覺察、觀照你的情緒”渔扎,是一句很殘忍的勸告硫狞。這依然暗示著,你的情緒是不好的晃痴,它不能被...
    Miss柳閱讀 603評(píng)論 0 1