寫在開頭:
????? Android源碼的過(guò)程,動(dòng)輒好幾千行、好幾萬(wàn)行代碼,大多數(shù)人肯定是看著就雙卵一緊、背脊一涼,一句“我CAO NI MA BI”就close掉頁(yè)面,略過(guò)了!而且也或多或少的會(huì)覺得,這些東西都應(yīng)該是大神級(jí)別的人物寫出來(lái)的東西,真害怕自己領(lǐng)略不到大神們的奇思妙想和鬼斧神工。?
????? 對(duì)我而言,最開始也是這樣的。但是當(dāng)鄙人靜下心來(lái),緊一緊本人的蛋,收一收菊花,邊扣著鼻屎,邊咬著牙去慢慢看的時(shí)候,首先發(fā)現(xiàn)的是在注釋里還是有好些拼寫錯(cuò)誤(看來(lái),是人寫的東西,就一定會(huì)有錯(cuò)誤和漏洞的啊),接著就是有些類的層次設(shè)計(jì)真是看不懂如此的意義在哪里,還有就是類結(jié)構(gòu)的設(shè)計(jì)以及方法的邏輯結(jié)構(gòu)和處理是好生奇怪?;蛟S是我才疏學(xué)淺吧,真沒看出來(lái)大師、大神們、或者上古神獸們的匠心獨(dú)運(yùn)在哪里。這里會(huì)陸續(xù)羅列一些我在閱讀源碼的過(guò)程中的一些分析和疑問,與所有的開發(fā)者一起共勉!



以上三張圖片沒啥名堂,只是這篇內(nèi)容所關(guān)注的東西的核心信息的介紹而已。接著來(lái)看這個(gè)類的幾個(gè)核心代碼:

getSpanEnd(Object what)、getSpanFlag(Object what)的處理和getSpanStart(Object what)是一樣的結(jié)構(gòu)。那么可以得知成員變量mSpanData的存儲(chǔ)結(jié)構(gòu)是[{start, end, flag},? , , ]邏輯上是一個(gè)int[][3]的二維數(shù)組,只是以一維數(shù)組的形式來(lái)操作。
那么問題來(lái)了:每次操作都得有四則運(yùn)算(涉及到數(shù)組遍歷是將產(chǎn)生大量的乘法運(yùn)算),而且相關(guān)數(shù)據(jù)分布在兩個(gè)數(shù)組之中(mSpans、mSpanData),為啥不單獨(dú)設(shè)計(jì)一個(gè)數(shù)據(jù)結(jié)構(gòu),來(lái)維護(hù)所有內(nèi)容,在邏輯上更直觀,處理起來(lái)也更方便。這里僅僅只是為了炫技增加代碼的復(fù)雜度,還是Java中沒有像C那樣的數(shù)據(jù)結(jié)構(gòu),只能設(shè)計(jì)單獨(dú)的一個(gè)類,相比用內(nèi)容拆分以及在數(shù)組處理技巧上的時(shí)間耗費(fèi)來(lái)?yè)Q取維護(hù)一個(gè)類數(shù)組的內(nèi)存空間消耗,作者通過(guò)效率考慮選擇前者,是真的有啥特別的深意么?不懂!
我們?cè)賮?lái)看核心的三個(gè)方法:

這個(gè)很好理解,沒啥可說(shuō)的,但是看看setSpan方法,可是讓我大吃一驚,好生奇怪:

第一個(gè)if語(yǔ)句對(duì)flag的判斷,就讓我好生奇怪,估計(jì)是我確實(shí)不能完全理解這個(gè)類的使用,setSpan為啥要先對(duì)本來(lái)要set的flag做判斷,那這個(gè)set還有啥意義?而if(mSpanCount + 1 >= mSpans.length)這個(gè)if判斷,要知道m(xù)Spans.length和mSpanCount++都得在該方法里面被操作的(而且還是這個(gè)if語(yǔ)句之后),永遠(yuǎn)都會(huì)是true(排除在線程不安全的情況下)的if判斷,有何意義?難道真的是我才疏學(xué)淺?
接著也是最后的超級(jí)大招兒:

這個(gè)方法,寫得是相當(dāng)?shù)钠婀?,完全不明就里。按我們正常的思維,一個(gè)span生效的范圍就是字串的某一子串,那么for循環(huán)內(nèi)部的那幾個(gè)if條件判斷,就是好生奇怪了!不懂!還是for循環(huán)內(nèi),count作為if條件,來(lái)對(duì)篩選結(jié)果做處理,大家不覺得有些怪怪的。是不是感覺很是多此一舉,直接累加返回結(jié)果數(shù)組不久行了么。以及臨時(shí)變量ret1做程序結(jié)構(gòu)的輔助,有這個(gè)必要么?更不用說(shuō)跳出循環(huán)后,在對(duì)最后的返回結(jié)果處理的時(shí)候,真真的不明白代碼這樣寫的意義何在,最初直接一個(gè)預(yù)分配一個(gè)T[0]的ret數(shù)組,有匹配結(jié)果后,直接append,我想效率不會(huì)是很差的吧!或者給一個(gè)T結(jié)構(gòu)的鏈表,最后結(jié)果處理成T[]返回!作者這樣count==0、count==1的設(shè)計(jì),哎呀,真心的看不懂??!
OK,分析到這里就結(jié)束了,本來(lái)不是一個(gè)和復(fù)雜的類,代碼也不是很多,只是我在看的時(shí)候,遇到的這些個(gè)問題,確實(shí)讓我好生困惑,這里寫出來(lái),希望有大神能看到,來(lái)鄙視我也好、解答困惑也好,給些我能明白的解釋!要說(shuō)我去按我的思路去重寫該類,也不是不可以,只是因?yàn)槲矣腥绱硕嗟睦Щ?,說(shuō)明可能我還沒能完全理解的這個(gè)類的結(jié)構(gòu)和用法,不敢冒此大不韙!
Anyway,這個(gè)SpannableString類名改成DecratableString或許更貼近它實(shí)際用法的意思!不是么!