標籤:
19.怎麼使用SourceInsight?19.1用途
我們主要使用SourceInsight進行源碼分析和尋找,主要是尋找我們所需要的檔案/類的位置。對於一套源碼,擁有幾十萬甚至更多個檔案,我們可以將這套源碼匯入到SourceInsight的工程裡,然後通過它的搜尋功能,便能快速給出我們搜尋結果:是否有這個檔案,同時可以直接開啟進行代碼閱讀和修改同步等操作。什麼時候需要這麼做呢?舉一個例子協助理解:
當我們需要解決一個PR或驗證一個問題時,難免會涉及到一些並不熟悉的檔案(布局、資源等xml檔案等)/類,這時候,僅僅通過Eclipse或者直接去檔案夾下面一個一個尋找的話,無異于于大海撈針費事費力還不一定能找到。這時候,通過SourceInsight便可以在幾秒鐘之內完成尋找任務,何其方便省事!
它的原理是對源碼(你所選取的目錄)下的所有檔案建立索引,當你輸入檔案名稱進行搜尋時,它便可以快速定位並顯示出來。
19.2安裝
因為我們是在Ubuntu下開發,而SourceInsight這個工具是Windows平台下的,因此涉及到安裝問題。在這裡特別說一下如何進行安裝:使用wine進行安裝。方法如下:
先下載SourceInsight的安裝檔案,一般均為尾碼為.exe的執行檔案,比如sourceinsight.exe,拷貝到一個儲存目錄,例如這裡使用/local目錄;
開啟終端,輸入安裝命令:
$wine install /local/sourceinsight.exe
安裝好以後開啟,將SN碼複製進註冊框即可。
也就是說我們使用wine進行安裝,以後要使用的時候,在Ubuntu系統的狀態列下的Application中,會看到Wine菜單,點擊它會彈出Programs檔案夾,在其中便可找到安裝好的SourceInsight檔案夾,點擊它的logo即可運行。
19.3使用
最後講一下使用SourceInsight的方法:
1.在最上面的功能表列中,點擊Project→New Project;
2.在彈出的對話方塊中,點擊Browse,選擇所需要匯入的工程目錄。
這裡特別說明一下:匯入整個工程或者匯入一個模組均可,例如匯入yarism-v1.0-dint或者下面的一個模組Settings。區別是匯入的工程越大,它的初次匯入時間越久(檔案越多越花時間,可以理解)。但從使用經驗來看,直接匯入一整個項目後,在搜尋的時候也不會有特別明顯的卡頓。因此,作者個人一般是一整個工程全部匯入的。
3.然後,起一個工程名(這個名字是用來在SourceInsight中標記的,並不影響實際源碼,因此請放心隨意起名),為了便於記憶區分,一般即使用源碼工程名,例如使用eyelike-v1.0-dint。
然後點擊OK,彈出一個確認的視窗,繼續點擊OK。這時彈出下面視窗:
圖x SourceInsight匯入源碼
預設選中的即為之前所選源碼目錄(註:作者在時匯入的是Kitkat-v1.0-dint源碼,因此圖中非eyelike-v1.0-dint,請知悉不要疑惑)。點擊右側的Add Tree按鈕,等待匯入完全。(整個源碼工程需要較長時間,需要耐心等待)。
4.匯入完全後點擊Close。然後,在下面輸入框中輸入任何想要尋找的檔案,即可看到檔案路徑等資訊,單擊所要查看的檔案,即可在左側開啟該檔案。
圖x SourceInsight搜尋檔案
以上搜尋操作即可滿足我們平日裡的需求,是不是非常方便簡單!當你關閉該工程後,可以再次點擊功能表列最上方的Project,選擇Open Project,然後選擇所要開啟的工程即可。
20.如何單編一個模組?
前面講了代碼的全編譯,但往往耗時較長(例如作者目前使用的i7處理器+8G記憶體,全編一次Android4.4 Kitkat源碼需要5小時多)。實際開發中,我們一般只是對模組進行單獨編譯(單編之前必須先進行過全編譯)。例如我只對設定模組做了修改,那麼就只是單編設定模組,然後將該模組單獨刷進手機裡進行驗證即可。
全編譯分MTK平台代碼和Google源碼,單編也是一樣的。
先講在MTK平台下單編一個模組的方法:
1.進入源碼目錄,例如eyelike-v1.0-dint,輸入如下命令(編譯MTK所提供的基準代碼為例):
$cd /local/eyelike-v1.0-dint/
2.輸入編譯命令:
$./makeMtk –t mm packages/apps/Settings/
說明:上面命令中packages/apps/Settings/為模組路徑。
將單編後的模組刷進手機的方法如下:
$adb push out/target/……
省略符號表示模組在系統中的路徑,具體查看方法是:在單編完成後,終端會返回一些資訊,其中包含了兩個輸出檔案,均是全路徑的格式進行顯示,其中尾碼為.APK的全路徑是編譯後的apk在out目錄的全路徑,其中的項目名稱後面的部分即為該模組在手機系統中的儲存路徑。首先將out目錄中的全路徑複製到push命令之後,然後再將手機的儲存路徑複製到最後,中間用空格區分即可。
特別提示:有時候會報出許可權不夠,adb remount一下即可。
然後講Google源碼的單模組編譯方法:
1.進入源碼目錄,例如kitkat-v1.0-dint,輸入如下命令:
$cd /local/kitkat-v1.0-dint
2.輸入命令:
$source build/envsetup.sh
說明:載入所有所需的系統內容變數。
3.輸入編譯命令:
$mmm packages/apps/Settings/
說明:上面命令mmm後面的部分為模組路徑。
4.輸入命令:
$make snod
說明:對於Google的源碼驗證只能在模擬器中進行。因為Google源碼中是不包含硬體驅動等內容的,因此,不能向單編MTK平台代碼直接將該模組push進手機進行驗證測試。要使得編譯後的單個模組在模擬器中生效,就必須瞭解載入模擬器的機制。簡單講,模擬器在開啟的時候,會載入下面路徑:
/local/kitkat-v1.0-dint/out/target/product/generic
中的system.img檔案,而各模組的內容均包括在其中,如所示。因此,如果我們編譯了一個模組後,只要保證將編譯所做的修改更新到該system.img中,然後重新開啟模擬器即可看到修改的效果。而上面命令的作用,就是使單編後的修改在system.img中更新生效。
圖x system.img檔案
5.最後,重新啟動模擬器即可,命令如下:
$./out/host/linux-x86/bin/emulator
特別說明:輸入上面命令後即可啟動模擬器。要關閉該模擬器,直接點擊模擬器右上方的X按鈕即可;也可以在當前終端中按下Ctrl+C按鍵組合。另外,第2、3條命令,在一個終端中只需要輸入一次即可,以後只需要鍵入第4條命令即可。但是,如果開啟了新的終端,則需要重新輸入以上所有命令,這點需要特別留意。
21.具備實際項目開發水平的必備技能?
至此,再停下來做一個小結:
我們已有了一個較為熟悉的模組,能夠進行源碼的下載、更新、全編、單編,能夠查看PR,能夠根據PR需求進行代碼修改。好有成就感和踏實感是不是?此時,只要在閱讀學習代碼和演練PR的時候沒有自我欺騙,應該已能初步負責一些簡單實際專案工作了!恭喜你!
但是,還有一個重要的部分我們還沒有涉及。是什麼呢?——各種提交相關的操作。是的,包括代碼提交、字串提交、圖片提交等等。難道不是嗎?
22.如何提交字串和圖片?
我們使用MSGM網站來進行管理項目中的字串和圖片資源,網址為:http://eyelike.com/msgm/login.aspx。帳號的申請,首先要在網站登入介面進行註冊。如所示:
圖x MSGM網站註冊
帳號資訊自己按提示填寫即可,沒有特殊規定。然後需要發郵件向整合組組長進行申請Approved。Approved通過後,登陸後進行嘗試即可,其具體使用比較簡單(不過還是推薦向資深同事請教,5分鐘的時間將節省幾小時的嘗試,並能有效習得如何避免犯錯)。
這時,大家肯定會產生疑惑:為什麼要提交字串和圖片?請看下面內容。
23.為什麼要提交字串和圖片?23.1資源分離的原理
要解釋這個問題,這就必須講一下資源分離的機制了!
系統定製是我們公司作為國際性公司的特色(例如華為手機,明明是使用Android系統的手機,開啟手機為什麼會看到huawei?為什麼會有各種huawei的應用和元素在裡面?當然是因為我們做了文章和工作,這就是我們做了系統定製),而系統定製的一個重要目的是資源分離。資源分離的主要內容是將代碼與資源(片、字串、聲音、相關定製值等)分離開。
如何分離開呢?首先講未進行資源分離時的情形,比如Google Android源碼,我們進行編譯使用的是make命令,而make命令的運行機制即是通過多個.mk檔案,將源碼中分布在各個檔案夾下面的內容一個個按照一定的邏輯順序找到並轉換為機器認識的形式。那麼,我們將原來和代碼在一起(離得比較近)的資源分離出來(統統抽出來放到一個特殊的檔案夾/目錄下面)。對於這些多個.mk檔案造成的影響就是,它們找不到這些被移走的資源檔了。那麼,我們便想辦法對這些檔案的內容進行修改,使得它們重新知道那些被移走的檔案到哪裡去了,進而在編譯的時候能夠找到它並產生完整的輸出檔案。
概括地講,就是通過對編譯系統的編譯檔案的修改,從而改變它的編譯機制。我們因此最終實現建立了一個新的分區(partition)cuspack,將資源分離,並有了一套自己的解析定製資源的機制。
直觀地講,我們最終做到的效果是將一個代碼和資源在一起的APK,分成只有代碼的APK和只有資源的APK兩部分。例如,本來Google源碼中Settings編譯後產生一個Settings.APK的檔案;而在經過系統定製後,將編譯產生Settings.APK(只有代碼)和Settings_res.APK(只有資源)兩個檔案,其中Settings_res.APK將存放在cuspack分區當中。
上面的兩種闡述,大概講清了系統定製的核心內容。想要深入理解,最好請教整合組framework的同事。當你能非常熟稔地掌握各個編譯控制檔案的邏輯時,便完全可以在兩個Team之間任意遨遊了(要花很多時間學習熟悉,而且對C語言和指令碼要求較多,因為大部分.mk檔案是用C語言編寫,而且牽扯較多指令碼工具的使用;這個已經和我們的Android系統上層開發維護跑題甚遠了,就此打住)。
23.2資源分離的優點:
最後說一下資源分離的優點:通過資源分離,我們將世界各個不同地區、不同電訊廠商的不同要求所產生的各種修改問題,縮小到只需要修改定製的資源上來。如此一來,核心代碼基本不需要進行修改,所有工作由Perso組代替完成,大大降低了修改不同需求所帶來的人力消耗和維護成本。
23.3原因綜述
正是因為有了這樣的機制,誕生了一個組:Perso組,專門負責這些定製資源的管理。為了提高效率,他們使用一個叫做MSGM的網站。通過它,可以方便地與UE(美工/設計)、開發工程師進行資源的交流。因為不同地區的語言、風格等等差異,手機系統的上層應用會出現各種適配需求(翻譯、圖片等等),這些問題均由開發工程師在工程代碼中進行驗證、確認或修改。所以,提交字串和圖片便成了一項十分普遍和重要的工作了。
24.代碼的目錄結構?
作為上層開發人員,在主代碼根目錄有四個檔案夾操作比較頻繁:packages(各模組代碼主要位於此處)、frameworks(系統架構代碼主要位於此處)、mediatek(MTK代碼主要位於此處),而以“項目名_wimdata_ng”命名的檔案夾,則是各定製資源所在。其下,又分若干檔案夾:wcustores(主要存放圖片、聲音等資源)、wlanguage(主要存放字串資源)、wprocedures(主要存放各plf定製值)。如標註。
圖x 代碼主要操作目錄
25.如何提交代碼?
作為開發人員,解決的很大一部分問題是以PR進行記錄的。而大部分PR的解決又是以修改代碼為主要方式的。既然修改了代碼,怎樣才能提交到伺服器?這部分特別重要,因此下面將花費較大篇幅進行詳細講解。
提交代碼的步驟:
25.1提交前的確認工作:
首先我們要確保已經有代碼被修改,其次確保修改後的代碼可以編譯通過,第三要確保所修改的代碼著實可以滿足PR需求。達到這三個要求,即可安心提交。否則,千萬不能提交,一定要保持嚴謹的態度使得三個要求具備,缺一不可。
下面詳細闡述這三個要求的具體內容:
一、很明顯,如果代碼沒有被修改,提交是沒有意義的,這點不多說了;
二、修改後的代碼編譯可以通過,可以保證不會影響整個源碼的編譯工作。即使你所修改的功能不正常,但一般不會影響別人的模組和功能。這對於團隊協作的開發模式,尤其又是代碼量巨大的工程來說是非常重要的。因為一旦你的提交導致源碼編譯報錯,其他人的工作都會受到影響,從而降低整個團隊的開發效率。
三、我們的修改是為瞭解決問題,如果所作代碼的修改不能有效解決問題,那麼提交上去只是多此一舉。而且會面臨被測試人員打回的風險(PR往往要送到測試部門的測試工程師那裡去進行驗證,既然沒有滿足修改需求,當然會被打回重新修改),而這是非常嚴重的品質問題。對於一個軟體開發工程師來說,這無疑說明你的能力水平的低下,將嚴重影響你的績效(和工資獎金掛鈎的評比工具,大部分是以打分的形式進行);對於測試工程師來說,使得他增加測試工作量,浪費人力;對於整個項目來說,加長了PR生命週期,拖慢了整個項目進度。由此可以看出,真是有百害而無一利!
然而,怎麼避免出現嚴重的品質問題呢?答案是仔細嚴謹地修改代碼,並一定做好本地驗證工作。
25.2提交代碼的方法:
1.開啟終端,進入儲存目錄(本例中進入/local目錄),敲入下面命令:
$cd /local
2.建立代碼提交目錄,例如我們的本地源碼目錄為:kitkat-v1.0-dint,在其中進行了修改,那麼可以建立一個目錄名叫做kitkat-v1.0-dint-temp(名字隨便起,便於標識區分是哪個項目的提交目錄即可)的檔案夾(不使用命令直接手動建立當然也是可以的):
$mkdir kitkat-v1.0-dint-temp
3.進入該代碼提交目錄:
$cd kitkat-v1.0-dint-temp
4.從伺服器同步項目manifest檔案,即代碼下載命令的前面部分(本例的代碼下載命令為:repo init -u [email protected]:aosp/manifest -m kitkat-v1.0-dint.xml && repo sync):
$repo init -u [email protected]:aosp/manifest -m kitkat-v1.0-dint.xml
說明:此時,在這個代碼提交目錄即有了我們的下載設定檔,與我們的源碼目錄kitkat-v1.0-dint中的一致,只是現在我們還未下載任何代碼進來。下面是關鍵的一步,即下載我們需要提交的庫。這裡涉及到庫的概念,即我們的一套源碼,在伺服器中是以庫為單位進行儲存的(類似於模組的概念,只是劃分的維度可能會有所不同)。因此,我們的提交也是對應於庫進行提交的,最直觀地說明就是,我們必須在一個檔案目錄下面進行代碼的提交,而這個檔案目錄,就是一個“庫”。
我們上層開發主要涉及到的幾個庫為:frameworks/base(在源碼目錄/frameworks檔案夾下的修改提交到該庫)、packages/apps(在源碼目錄/packages檔案夾下的修改提交到該庫)、xxx(項目名)_wimdata_ng/wprocedures(在源碼目錄/ xxx(項目名)_wimdata_ng下修改了plf檔案後提交到該庫)。
本例中以修改SettingsProvider.java類後的提交為例進行說明,該類在源碼目錄/frameworks下面,因此,
5.我們鍵入下面命令,從伺服器同步該庫的代碼:
$repo sync frameworks/base
說明:此時,我們的kitkat-v1.0-dint-temp目錄即是伺服器中該庫的最新代碼,我們可以想到,與我們本地的kitkat-v1.0-dint目錄中的同樣的庫代碼中,有一個類SettingsProvider.java的代碼是不同的。我們的提交所希望達到的目的便是讓伺服器中的同樣的庫同樣的類的代碼與我們本地kitkat-v1.0-dint目錄中的代碼一致。下面便需要藉助一個叫做Meld Diff Viewer的對比工具了(後面有教如何安裝)。
6.鍵入命令:
$meld
說明:此時可以開啟Meld工具的視窗介面。
6.1點擊最上面功能表列的File,點擊New,出現如所示介面:
圖x Meld代碼匯入
6.2點擊圖中Original後面的Browse按鈕,匯入未修改的源碼,這裡即下載下來的kitkat-v1.0-dint-temp目錄中的SettingsProvider.java類;
6.3點擊圖中Mine後面的Browse按鈕,匯入修改後的源碼,這裡即我們的本地源碼kitkat-v1.0-dint目錄中的SettingsProvider.java類。
6.4然後點擊OK,即可看到兩套代碼中該類的對比,如所示:
圖x Meld代碼對比
說明:中右側即為本地修改的代碼,而左側即為伺服器下載下來的未修改的代碼,綠色標識出來的即為代碼有差異的部分。中間有個黑色箭頭,點擊它即可將右邊的修改插入到左邊去。
6.5點擊黑色箭頭,將修改匯入左側代碼中;
6.6點擊最上面的Save按鈕儲存該修改。
說明:此時,kitkat-v1.0-dint-temp目錄中的程式碼程式庫便與kitkat-v1.0-dint中的對應的程式碼程式庫相同了(本例中是frameworks/base庫)。
至此,大家心中應該慢慢有所明了。我們接下來所需做的,便是將kitkat-v1.0-dint-temp中的代碼同步到伺服器上。
7.進入kitkat-v1.0-dint-temp目錄下的frameworks/base/:
$cd frameworks/base/
8.查看確認所做修改:
$git status
說明:上面命令可以查看目前的目錄是否有修改,是否有提交更新到伺服器,如果有修改會將修改的檔案顯示出來。
9.接著輸入:
$git diff
說明:這個命令可以將修改的代碼顯示出來,同前面小節所講在Gerrit網站查看修改記錄的效果一致。
10.輸入提交代碼命令:
$ /automount/tools/scm_tools/tools/patch_delivery_cli.php -p ff
說明:至此,所有確認工作OK。
上面命令表示使用patch_delivery_cli.php指令碼工具來提交代碼。還記得前面講如何查看別人的PR修改記錄嗎?當時提到我們提交代碼成功後指令碼工具會自動在Bugzilla上面的該PR的Comments中插入修改記錄的連結,那個指令碼工具就是這裡的patch_delivery_cli.php。這下前後連貫起來了,是不是有中恍然覺悟豁然開朗的感覺?又該恭喜你了!
11.接著根據終端出現的提示,輸入對應的資訊:
11.1第一個是項目選擇,它會提供所有項目的名稱編號,根據我們的PR屬於哪個項目,輸入對應數字編號按Enter即可。
圖x patch_delivery介面
11.2接下來是輸出Bug Number和patch comments等資訊,如所示。這裡特別註明:PR號一定要填寫正確,Comments從Bugzilla網站上複製過來即可(我們在提交代碼的時候,一般都同時開著Bugzilla,以複製這些必要資訊)。其餘根據提示填寫即可,沒有強制規定,但提倡使用嚴謹的語言風格。另外,在patch comments中填寫完畢後,按Enter鍵,然後再出入一個“.”,然後再按Enter鍵才可以進入下一步。其他選填項如果不想填寫,也均使用“.”表示結束,這點需要特別知會。
11.3最後,確認command輸入yes。
說明:此時,代碼提交的任務便提交到了Gerrit網站。又得回顧一下之前所講,Gerrit網站是用來做代碼審核的。
12.登陸Gerrit網站,此時可以看到我們剛才提交的代碼已經對應產生了提交任務,點擊該任務,設定代碼reviewer,如所示:
圖x Gerrit添加Reviewer
在Add Reviewer按鈕左側的輸入框輸入reviewer的郵箱,然後點擊該按鈕即可完成添加。添加成功後可以在中紅色方框標識的地方看到reviewer的資訊。
圖x Gerrit添加Reviewer成功
這樣Gerrit網站就會自動發郵件到你所設定的reviewer的郵箱,當他登陸Gerrit網站後就可以看到你的修改審核任務。
13.等待審核通過,通過後,重新登入Gerrit網站。便可以在Gerrit網站上發現一個Submit的按鈕,如所示:
圖x Gerrit審核通過
14.點擊Submit按鈕,當該patch顯示如紅色方框資訊後,表示大功告成!
圖x Patch提交成功
特別說明:
一、如果沒有審核通過,你將會受到Gerrit網站自動發給你的郵件通知,你需要做的是重新查看並修改代碼,然後再重新提交。這個操作就不用多贅述了吧!
二、有時候,我們提交代碼比較著急,希望能儘早被審核通過,那麼,提交後直接去代碼reviewer座位上告訴他比較緊急請他儘快review,是最好的辦法。
26.怎麼安裝Meld Diff Viewer?
Meld Diff Viewer是Linux平台下的一款對比工具,可以進行檔案、目錄的對比。當然,也有很多人使用另一款對比工具Beyond Compare,其為Windows平台下的一款強大的對比工具,但是收費需要破解。既然我們本身就是在Ubuntu下面工作,那麼使用Meld便可以了。它十分簡潔,而且免費,對於我們提交代碼的對比工作,已經足夠使用。
如果系統中還未安裝,使用下面方式可以進行安裝:
1.開啟終端,輸入下載命令:
$sudo apt-get install meld
2.提示輸入密碼:
$eyelike(原生Ubuntu系統登入密碼)
如果出現
“Sorry, user user is not allowed to execute ‘/usr/bin/apt-get install meld’ as root on aclgcl-ubnt22”
的錯誤時,說明sudo使用權限設定還不OK。進行如下設定(因為一般公司中出於安全考慮,管理員權限都沒有下放到開發工程師個人,所以去請整合組同事幫忙設定一下,需要root許可權):
1.先輸入命令:
$su
2.然後輸入密碼:
$xxxxx(這個整合組管理系統配置的同事知道)
3.然後進入root賬戶,輸入命令:
$vim /etc/sudoers
4.在其中添加添加user賬戶代碼,如下:
“(複製root賬戶代碼後粘貼,將root欄位修改為user即可)”
5.然後儲存退出,完成設定,即可正常安裝軟體。
27.怎麼接手實際項目?
至此,已經可以獨立提交代碼了!這也預示著具備接手實際項目的能力了,心中難免激動又忐忑不安,這都是正常的。
其實,比較好的節奏是開始的時候接手一些預研任務。基本任何一個完整的項目,開始都有一段時間的預研,用來將參考項目(一般是之前已經開發的過的項目,很多問題類似,很多代碼可以參考共用)的一些功能需求預先熟悉,匯入到我們自己將要開發的項目代碼中來(此時你是可以使用參考的代碼修改來直接解決任務的)。預研任務的特點是難度係數較小,但是任務繁多,再適合熟悉代碼和練手不過了!所以,不要太擔心,你已經一步一步進入實際項目中開始有自己的產出了。
寄語
至此,一名合格的初級開發人員已然成型,假以時日熟悉各種操作和加深對模組代碼的理解和熟悉,便可達到“海闊憑魚躍,天高任鳥飛”的層次。本文只是將作者從初學到最終能夠接手實際項目的學習過程中所遇到的問題、所認為必須瞭解掌握的內容整理而成。萬事從無到有難,在茫茫不知所措時曾經極度渴望有人、有文章來指點江山;也曾遇到因為不瞭解一個小小的知識點而花費大量時間的時候。好在受到非常多的同事、負責的導師等人的協助指點,最終完成了項目前的學習。這篇文章便是對他們的感謝,也是為像曾經的我一樣懷著對Android開發的熱愛和激情的後來者所寫,希望其中的某些知識能實實在在協助到他們,給予他們學習的動力。文中難免有勘誤,希望自己沒有犯出誤導大家的根本性錯誤,這樣便滿足了。俗話說知識無止盡,還有非常多的東西沒有抒寫出來,也還有非常多的東西沒有學習。但是,相信只要我們有了足夠的基礎,有足夠多的耐心去學習摸索,那未講的未知的終將變為自己熟悉的、自己能力的一部分,併產生出更多更大的價值。末尾,贈一句:“我們都在路上,加油,與君共勉!”
最後附上我整理精選後的一些常用快速鍵和知識:
附錄一 Eclipse實用快速鍵
附錄二 Ubuntu常用終端快速鍵
附錄三 Vim編輯快速鍵
附錄四 PR/FR/RR/CR各是什麼
[email protected]
Android開發人員上手寶典(三)