如何在「Intelli J」上導入「AOSP」專案
目的
如何在「Android Studio」上導入「AOSP」專案。
概論
如果你們和筆者一樣,在踏入「BSP」領域之前是個「APP Developer」,或許你也會跟筆者一樣懷念「Android Studio」的開發環境。
雖然在「Linux」下有著號稱唯有「真工程師」才能駕馭的「編譯器之神」:Vim;但無奈本非天選之人,駕馭不能。
事實上,在「Android」源碼的閱讀上,還有許多不錯選擇,像是鼎鼎大名的「Source Insight」,老牌的「Eclipse」,或是微軟的「VS Code」等,都是有著各自的擁護者。
而筆者選擇的是「IntelliJ」,主要原因是它與「Android Studio」源自同根,筆者相對熟悉。
至於為什麼不乾脆使用「Android Studio」,主要原因是筆者仍然有需要開發「APPs」,想藉以區別。
其次是在專案中的「README」文件,其內容是針對「IntelliJ」,如下:
但無論是使用「IntelliJ」或「Android Studio」,其操作方式幾乎是沒有差異的。
正文
產生「IDE」的項目配置文件
若我們想要在「Android Studio」或「Intelli J」上導入「AOSP」專案項目,則我們必須先取得「IDE」的項目配置檔,分別為「.ipr」跟「.iml」。
但在開始產生配置檔之前,還有一些前置作業必須先完成,首先就是要先取得「idegen.jar」,必須藉由它才能夠產生「IDE」的配置檔供其辨識。
取得「idegen.jar」
首先,我們藉由編譯 「idegen」模塊的方式產生「idegen.jar」,指令如下:
source build/envsetup.shmake idegen
理論上,此時在路徑「out/host/linux-x86/framework/」下就能看到我們所需要的檔案:「idegen.jar」,如下:
若沒有,可以嘗試「make clean」後,在執行上述指令。
若依然不行,可以嘗試直接「完整編譯」後,在構建「idegen」目錄,如下:
source build/envsetup.shmake -j16mmm development/tools/idegen/
備註一:因為「idegen」模塊為專案的模塊之一,因此「完整編譯」也會有同樣的效果。
備註二:「m」、「mmm」和「mmm」其實是編寫在「envsetup.sh」的方法,因此,若要使用該些指令,則必須先將之「envsetup.sh」啟動。
結果如下:
產生「.iml」與「.ipr」
在取得「idegen.jar」後,我們就可以藉由執行「idegen.sh」來取得「.iml」和「.ipr」這兩個項目配置文件,執行指令如下:
sudo development/tools/idegen/idegen.sh
完成後,專案根目錄底下就多了「Android.iml」和「Android.ipr」這兩個檔案,如下:
其中「.ipr」是主要提供「IDE」辨識的文件,其通常是保存專案相關的配置、設定等;而「.iml」則是紀錄著「modules」路徑及依賴關係…等。
更改「.iml」與「.ipr」的存取權限
當該檔案被產出時,它們權限設定皆為「唯讀」;而這會使得專案的配置無法被修改,所以我們要修改其權限為「可讀寫」,如下:
sudo chmod 777 android.imlsudo chmod 777 android.ipr
修改「.iml」項目配置文件
由於 AOSP 的專案非常龐大,除了「框架源碼」之外,其還包含「硬體驅動的代碼」、「配置文件」、「工具包」…等,而該類檔案多與我們的開發無關,因此,我們可藉由修改「.iml」配置,將不需要部份排除關聯。
首先,開啟「.iml」:
vim android.iml
找到「excludeFolder」屬性處,如下:
在「IDE」初次配置時,會讀取「excludeFolder」屬性中的路徑值,然後排除該路徑下的所有關聯行為。
若對「AOSP」有比較深入了解的讀者,可以自己依照習慣配置,或著依照下述方式配置:
當然,也可以乾脆不要配置,只是「IDE」在載入專案時的耗時比較久一些。
修改「IDE」參數設定
此處,筆者建議根據專案中的「README」去設定,如下:
首先,如說明,在「IDE」右下角指到「Configure」,如下:
然後選擇「Edit Custom VM Options」,並加入「-Xms1g」和「-Xmx5g」。
接著選擇「 Edit custom properties」,並加入下述設定:
idea.max.intellisense.filesize=100000
完成後,如下:
此外,亦可直接修改「設定檔」,如下:
修改「Linux」的「Watches Limits」
對於「Linux」的使用者來說,由於「Linux」有「Watches Limits」的限制,而「AOSP」的項目過於龐大,已經超出該限制,因此我們必須去修改它,請參考「IntelliJ」官方文件「Inotify Watches Limit」進行設置,如下:
開啟「AOSP」專案
點擊「Open or Import」來開啟專案,找到根目錄下的「Android.ipr」,點擊開啟後,就只能等待,這是因為「IDE」會在初次導入時進行關聯,因此非常耗時。
在專案中新增「JDK」和「SDK」
當載入完成後,點擊捷徑開啟「Project Structure」,如下:
當然也可以從選單「File / Project Structure」來開啟「Project Structure」,接著在側欄項目選擇「Platform Settings」下的「SDKs」,如下:
然後點擊左上方的「+」字號,新增一個自定義的「JDK」,如下:
並刪除其目前所有的「Classpath」和「Sourcepath」:
接著,新增「Android SDK」,方式與剛剛類似,只是剛剛是新增「JDK」,而現在是新增「SDK」,如下:
配置「Project」的「SDK」
在設定完「SDK」後,側欄選擇「Project Settings」下的「Project」項目,將剛才修改後「SDK」設為「Project SDK」,如下:
配置「Modules」
完成「Project」的設定後,接著換設定「Modules」,選擇同樣在「Project Settings」下的「Modules」項目,在「Dependencies」頁籤下,將所有的依賴項目全刪除,僅留下「Module source」和「Android API SDK」 兩項,如下:
刪除完成後,畫面如下:
設定「R」檔為「Source」
最後,將「R」設為「Resource」,同樣在「Modules」的視窗中,選擇的分頁為「Sources」;「R」的路徑如下:
out/target/common/R
對「R」點擊右鍵,將「Sources」選項打勾,如下:
按下「OK」就搞定了。
總結
實際上,「Google」並不希望「供應商」對「Android Framework」的源碼有過多的修改,甚至制定了一套「XTS」的認證機制。
在「8.0」以後,Google 預期硬體相關的實作應該藉由「HAL」方式串接,而非嵌入在「Android Framework」之中,以達到分離的目的,如下:
簡言之,就是盡量避免修改「Android Framework」;事實上,「SDK」的開發自由度並不高,基於某些理由,「Google」給予許多的限制,包含與使用者行為相關的,如「啟動流程」,又如「TV Launcher」的限制,如規定某些特定預載入「APPs」的擺放方式與位置…等。
事實上,根據筆者的經驗,多數在製造廠負責「BSP」項目的工程師,其主要的工作內容多為「系統整合」、「認證測試」…等;然而,在大多數的情況下,我們的需求僅是「閱讀」或「修改」,鮮少是去開發整個系統,在這樣的情況下,就不一定需要到使用「IDE」,其實使用「Vim」配合指令操作甚至可能會更順手一些。
雖然筆者講得好像很容易,但別以為這工作很輕鬆,因為,當追「Bug」可能必須從「APPs Layer」追到「Driver Layer」時,恩,就是那樣。