Android Support Library 編譯過了!

到了2018年,作為Android開發(fā)者,倘若沒看過一些Android源碼,都不好意思說(shuō)自己是Android工程師了吧?

之前一直是在GrepCode(http://grepcode.com/)上看的。這是一個(gè)相當(dāng)老牌的Android源碼在線查看網(wǎng)站。雖然上面缺少了近幾個(gè)新版本的Android 源碼,但勝在源碼種類多,除了Android,還有其他軟件的源碼可以閱讀;易上手,代碼之間能相互索引,查看方法引用、繼承關(guān)系、類的結(jié)構(gòu)和跳轉(zhuǎn)這些功能都很好用,還能方便在切換同一個(gè)文件的不同版本的源碼。令人悲傷的是,它已經(jīng)掛了好長(zhǎng)一段時(shí)間了。: - (

另一個(gè)源碼閱讀網(wǎng)站AndroidXRef(http://androidxref.com/)也很老牌,但用的不多。這個(gè)網(wǎng)站專注于Android源碼,從遠(yuǎn)古版本到最新版本都能在上面找到。功能夠用,可以查看方法應(yīng)用、類的結(jié)構(gòu)和跳轉(zhuǎn)這些。繼承關(guān)系、版本間跳轉(zhuǎn)這些就沒有。目前還活著,只是受限于國(guó)內(nèi)的網(wǎng)絡(luò)環(huán)境,訪問起來(lái)有點(diǎn)慢。

選擇在線的方式閱讀源碼,主要是嫌麻煩。一來(lái)是不經(jīng)???,主要是查疑難bug的時(shí)候看;二來(lái)是不方便,Android 發(fā)展了十年,源碼相當(dāng)龐大,有十幾個(gè)G之多,前幾年嘗試過clone,結(jié)果拉了幾天才拉完;三來(lái)是編譯環(huán)境不好配,官方的源碼編譯說(shuō)明看著不多,實(shí)際操作沒那么簡(jiǎn)單,之前的嘗試都失敗了;最后則是這兩個(gè)在線查看代碼的網(wǎng)站都能滿足看代碼的需求,也沒編譯的需求,也就一直這么過來(lái)了。

然而看源碼最舒服的方式莫過于直接用IDE(如Android Studio),功能多,用起來(lái)順手,而且還可以編輯。等等,編輯?還想改代碼不成?并不是這樣滴。架不住年紀(jì)大了,一些看過的源碼慢慢的就遺忘了。俗話說(shuō)好記性不如爛筆頭,編輯的需求,也就是給源碼加注釋加批注罷了。如果僅僅是看代碼的話,Android Studio通過SDK Manager下載Source Code就可以了。

需求變了,在線看源碼的法子,就行不通了。真是應(yīng)了那句話:天道好輪回,蒼天繞過誰(shuí)。不對(duì),應(yīng)該是躲得了初一躲不過十五,之前那些避開的麻煩,還是需要去面對(duì)的。

Clone Android Repository的全部源碼,這輩子肯定是不可能的。近期想看的是Support Library的源碼,所以我在程序員的網(wǎng)站GitHub上找到了AOSP-Mirror這個(gè)Organization,clone了一份support library (https://github.com/aosp-mirror/platform_frameworks_support)的源碼。

拉代碼的過程挺順利,用Android Studio打開,完了,Gradle沒法build過去。Build不通過就沒生成索引,沒索引就Android Studio就從IDE淪為普通編輯器,那些強(qiáng)大的功能全都用不上,還不如用understand。

好在,在某個(gè)風(fēng)和日麗月黑風(fēng)高的晚上,借著天時(shí)地利人和,通過命令行運(yùn)行Gradle得到的錯(cuò)誤輸出,一點(diǎn)點(diǎn)地改各類.gradle文件,最終把Gradle Sync這一步搞定了。后面又精簡(jiǎn)了一下改動(dòng)范圍,然后把這些改動(dòng),push到了自己fork的 platform_frameworks_support項(xiàng)目的buildable分支里。有需要的可以到這里(https://github.com/SR1s/platform_frameworks_support/tree/buildable)自取。

改動(dòng)的地方不多,涉及5個(gè)文件。改動(dòng)的內(nèi)容總結(jié)起來(lái)就是:

  1. 修改buildscript使用的maven庫(kù),引入了jcenter和google這兩個(gè)公共的maven庫(kù)
  2. 修改 dependencies 使用的maven庫(kù),引入了幾個(gè)公共的maven庫(kù),去掉了源碼里指向android源碼工程里prebuilts文件夾的那幾個(gè)maven庫(kù)
  3. 去掉settings.gradle里配置的幾個(gè)module,一類是外部module,即代碼不在platform_frameworks_support里的module;另一類是依賴的這些外部module的module,這幾個(gè)的代碼現(xiàn)在不關(guān)心,所以先挪去它們?cè)趕ettings里的配置(源碼還在)
  4. 修改gradle wrapper使用的gradle的下載地址,源碼里指向的是本地,也就是android源碼工程里防止prebuilts文件夾下的gradle的地址,這里改成網(wǎng)上公共的gradle版本的地址。

涉及的5個(gè)文件如下:

  1. buildSrc/build.gradle
  2. buildSrc/init.gradle
  3. buildSrc/repos.gradle
  4. gradle/wrapper/gradle-wrapper.properties
  5. settings.gradle
  1. build.gradle
    給buildscript添加了jcenter和google這兩個(gè)maven庫(kù)。源碼里指向的是源碼中的prebuilts目錄,這個(gè)目錄不在這個(gè)repo里,我去翻了翻,prebuilts目錄里東西非常多,也就是很大,拉下來(lái)不現(xiàn)實(shí),另外自己一個(gè)個(gè)單獨(dú)下也不現(xiàn)實(shí),還是直接用jcenter這類公共maven庫(kù)方便。添加google的maven庫(kù)是因?yàn)間oogle現(xiàn)在把自家?guī)焱锓牛瑳]有發(fā)布在jcenter里了。(后面我試了下,不加google的這個(gè)maven庫(kù)也是可以的)

  2. buildSrc/init.gradle
    這里改動(dòng)一個(gè)是注釋掉了enableDoclavaAndJDiff這個(gè)方法內(nèi)的實(shí)現(xiàn)代碼,這個(gè)是給project添加jdiff和doclava這兩個(gè)依賴和配置,一個(gè)是diff工具,一個(gè)是文檔工具,這兩個(gè)依賴都是android源碼里的其他工具的project,只是為了看代碼,用不著這兩個(gè),注釋掉也不影響。
    另一個(gè)就是去掉project.ext.androidJarprops.write這兩句,前者把a(bǔ)ndroidJar指向了prebuilts目錄內(nèi)的最新的android.jar,后者往local.properties文件里寫入配置。前者去不去掉其實(shí)無(wú)所謂,不影響,后面那個(gè)因?yàn)闀?huì)往local.properties寫入android.dir的路徑配置,從而覆蓋掉ide內(nèi)設(shè)置的android.dir,那個(gè)配置指向的是當(dāng)前工程的父級(jí)目錄,正常情況下,我們的sdk肯定不放哪里,因而build就找不到相關(guān)的工具出錯(cuò)了,所以要把這個(gè)寫入注釋掉,用Android Studio設(shè)置里的那個(gè)就行了。

  3. buildSrc/repos.gradle
    這個(gè)文件定義了一堆本機(jī)上的依賴庫(kù)的地址,實(shí)際上就是android源碼里的prebuilts目錄內(nèi)的一些具體的目錄。地址都放在ext.repoNames這里,然后通過下面addMavenRepositories方法,給RepositoryHandler加上這些maven庫(kù)。牢記我們沒有prebuilts目錄,這些maven庫(kù)指向的地址自然也是無(wú)效的。因此這里再加了一句ext.repoNames = [],把列表重置成空列表,這樣后面加這些maven庫(kù)的代碼就無(wú)效了。
    另一個(gè)是要讓Repository能找到依賴。原來(lái)官方代碼是讓gradle去prebuilts下找,現(xiàn)在我們把這個(gè)配置去掉了,依賴也就找不到了(不去掉也找不到啊哈哈),那么就要跟之前對(duì)buildscript做的事情一樣,加上公共庫(kù)。剛好下面有個(gè)if語(yǔ)句,在符合條件下,會(huì)給Repository加外部maven庫(kù),所以就注釋掉if判斷,讓內(nèi)部的代碼強(qiáng)制執(zhí)行,也就自然加上了外部maven庫(kù),依賴就能被找到了。

  4. gradle/wrapper/gradle-wrapper.properties
    這個(gè)很簡(jiǎn)單,把wrapper依賴的gradle的下載的地址改成網(wǎng)絡(luò)上的,之前的配置指向的是android repo的tools目錄,再次的,我們沒有這個(gè)。所以,改成從網(wǎng)絡(luò)上可下載的地址:https://services.gradle.org/distributions/gradle-4.4-bin.zip

  5. settings.gradle
    這里做的事情簡(jiǎn)單概括起來(lái)就是:

  6. 去掉了項(xiàng)目里的support-emojisupport-emoji-bundled、support-emoji-appcompat、support-emoji-demos這幾個(gè)module的定義,原因是它們或直接或間接的依賴了另一個(gè)不屬于這個(gè)repo的noto-emoji-compatmodule,這塊代碼目前沒想著去看,先不管。

  7. 去掉不屬于這個(gè)repo的module的定義,分別是doclava、jdiffnoto-emoji-compat這三個(gè),他們的源碼都在Android大項(xiàng)目的源碼的external文件夾里,是在想引入這幾個(gè)的,可以去down下來(lái),然后配置。

相關(guān)的代碼變更都在這個(gè)commit(https://github.com/SR1s/platform_frameworks_support/commit/a23529ad2ca019624af9213daf2836e78ce579a2)里,大家都是工程師,一看就懂。

終于可以好好看代碼了,歐耶。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容