【談】分享Android應用工程師如何切入Framework

前言:

      華爲發佈鴻蒙,分佈式微內核全場景新一代操作系統,多終端一次開發,餘承東宣佈鴻蒙系統隨時可用於手機,現有android應用全兼容,而且完全開源。鴻蒙在發佈會上最爲人稱道的一點是‘開源’,畢竟能經得起世人檢驗的代碼,纔是靠譜的產品。

      當然在發佈會上有支持鴻蒙的,也有給鴻蒙潑冷水的,鴻蒙需要開發者加入,開發者也需要通過代碼更深入的瞭解鴻蒙。一邊自稱開源,一邊一行代碼也看不到,會讓人高度懷疑鴻蒙項目的完成度。

      筆者站在一個Android系統開發工程師角度去怎麼看待鴻蒙呢?,筆者只是更加得期待有國產自研的智能操作系統,不管好與壞 畢竟都是國產智能的操作系統新的開端,我們應該用美好長遠的眼光去看待它。

     文章的開始讓我們致敬華爲,致敬鴻蒙。

分享

       Android7.0 系統(framework)定製、修改、移植 總結

      Android7.X 源碼下載、編譯、運行系統詳解(ubuntu 16.0.4)

      Android - [MT6737] MTK 編譯環境搭建

      Android 高通8909 系統之路之 裁剪系統 一

      Android-MTK系統- 系統常用修改點

      Android - MTK系統源碼結構

      首先寫出此篇的文章的目的僅僅是分享給那些做應用層不知道怎麼切入Android framework/kernel 的工程師。

      其實筆者進入Android 系統開發的時間也就3年,筆者給自己定位的一名產品研發工程師,爲此筆者不想極度的去深入研究,但是一定要熟練,但是筆者還是能夠分享出一些微不足道的經驗給基於需要此篇文章所講述的經驗。

      筆者最先開始其實是做嵌入式、單片機、Qt C++ ,由於很喜歡C++ 這門語言,這可能也源於我在大學裏對C、C++ 培養的喜好,特別是喜歡C直接操作內存,能夠透徹明白,原來內存是這麼變化的。但是由於前幾年移動互聯網的興起,筆者是個‘隨波逐流’ 的工程師,於是我最後打算進入Android開發領域,爲什麼是學Android 而不是IOS?

       1:IOS設備成本高,不便於研發。

       2:筆者在學Android之前有特地初步的瞭解Android架構,學Android最重要的原因是 Linux。

       3:當前如果一直都處在Application 層開發的 對Linux的接觸會沒那麼深,並且系統編譯都是要在Linux下進行。

       4: Android系統開源,意味着不像IOS一樣,基本都在應用開發,並不能去了解整個系統的架構。

       5:對於Android在學習上的拓展性極強,Application->framework->kernel +Linux 學習的方向相當明確,而且在當時已經想到未來將會是物聯網的天下,而Android設備將會是物聯網設備的首選之一,其原因爲Android系統開源,定製性強。

       6:學完以上,會順帶的加強Linux操作系統的使用,以及一些腳本的使用,摸通了Linux 一些規則加上時間經驗的沉澱,熟悉了之後可以做些什麼? Linux作爲目前主流雲服務器的系統 ,好了 ,機會來了。

       7:好處N多,說不完,在此省略。。。

     筆者在移動互聯網高峯期混了一波後,終於踏上了物聯網設備研發之路,這個過程很艱辛,筆者從頭到尾都是自學得,有人教當然事半功倍。人們常說,學好Linux 到哪裏都餓不死,後面想下這句說的真的很對。

     直接進入主題,那麼現在問題來,App開發後如何轉framework,做什麼?怎麼做?

    分享點1: 記住:【開發很簡單,只是開發的環境差異,只要熟悉了這個環境,你會發現原來是這樣】

     做什麼?怎麼做?:

            首先要明白應用層轉framework層需要學習一些什麼,路線步驟是怎麼樣的。這邊大概列一些需要學習的點

            1:下載源代碼進行編譯(編譯前需要搭建環境,如你開發應用需要 SDK,JDK一個道理 ) 【看 -> 9】

            2:如何使用Linux服務器(虛擬機上運行Ubuntu& centos  或者 自搭建的都行)

            3:閱讀代碼工具的使用 source insight 導入源碼,Android Studio導入源碼  

            4:編譯環境,網上尋找資料,根據Android的系統版本搭建對應環境如4.4 和 5.1以上可能就會存在環境的差異,如JDK使用的版本不一樣,而且學會如何在Linux下搭建不同 JDK環境,系統源碼很龐大,他需要用到各種庫,  不懂的話百度一下你就知道。

            5:可能在編譯中會存在各種各樣的問題,編譯命令?如何燒寫,百度谷歌基本爲你們都解決了這個問題或者其他方式來解決都可以。你會發現在解決問題的時候你是在積累經驗以及在潛移默化的學習Linux的一些命令操作和系統的使用。

            6:編譯成功後,切記一定要有真機來調試, 修改代碼在進行運行對比下結果,你應該初步瞭解下Android系統整個源碼的每個目錄對應的作用是什麼? 編譯後out   目錄下產生的一些文件夾、文件 是什麼作用。

            7:剛從App轉到Framework 可以從系統應用層入手,因爲他們基本和App開發一樣,只是編譯的方式不同。這些應用在哪裏?手機連上USB 通常 adn shell  -> cd system    下 一般會有 app 或者 priv-app 裏面的應用都是系統應用級別,而system目錄下的framework文件夾裏 纔是framework的核心。

            8:學習需要循序漸進,從應用->系統應用->系統框架,這裏面重點再講一下,必須要有真機或者開發板來實踐操作,只一味地閱讀系統源代碼並不能快速地提升。

            9:有一些沒有真機或者開發的開發者來說怎麼辦?可以網上購買一些Android 開發板,一般開發板都會配套 開發板的資料以及編譯環境,開闆闆源碼齊全的資料等,賣家也會提供一些比較優質的服務器。

           10:總結一句話,開發很簡單,難的只是開發的環境差異,只要你熟悉了這個環境,你也就知道就這麼回事。

           基本的環境,編譯命令熟悉之後,通過時間去研究,修改,編譯 Android的各個模塊,很快就能找到一些規律性 。

   分享點2: 由於系統源碼相當龐大,系統修改點各處都有,在Linux上需要git來管理整個源碼。如修改了哪些,在哪個路徑,想回滾到某個版本   非常便於系統源碼的管理。

 學習過程:

       Android framework的系統性知識網上是極少的,零散性的比較多,後續可能會碰到很多需求也會發現網上搜不到或者根本沒有這個參考答案,那怎麼辦?通過時間的學習項目的積累+技術的沉澱 慢慢得摸透了規律其實你會發現,按照自己發現的套路規律來,很簡單。

       其實Android系統整個系統的貫穿的,筆者認爲學習的工程師應該給自己規劃路線,清楚需要學哪些,模塊化的去學習,可能Android framework它太龐大了,甚至會發現根本學不完,應該說是真的學不完,那麼接下來我建議剛從Application轉framework 的學習過程,模塊要怎麼劃分:

 【學習的時候一定要建立在編譯環境能夠順利搭建,Linux基本命令熟悉並且有真機或者模擬器調試】

   第一階段:

         1:系統應用(服務)的初識

           在  package/apps   或者  framework/base/package/apps   有的源碼可能在 vendor/*/*/apps    都會有着系統應用程序的源碼[在閱讀修改源碼前 不妨先了解一下每個應用下Android.mk  腳本中每行代碼對應的作用] ,接下來你會發現代碼和應用層基本類似,區別在哪裏?   1:系統應用通過Android.mk 進行編譯  2:可能部分系統應用結構極其複雜,模塊很多  3:系統的編碼規範,各種設計模式的運用和App有點差異化   

          在這裏只是簡單描述並不進行技術上的深入,筆者建議必須深入研究的系統應用:

           1:framework/base/package/apps/SystemUI

           2:package/apps/Settinggs

          基本常用的系統應用:

          1:package/apps/Dialer(依賴於InCallUI)

          2 : ackage/apps/Launcher*

          部分系統應用會依賴於一些服務應用 如 Dialer 依賴於 \packages\services\Telephony  (frameworks\base\services 下的)

          後續只要用源代碼瀏覽工具就可以輕鬆知道調用的是哪個模塊。

         [注:有的源碼可能目錄不一樣,但基本相似]

     當你研究了系統應用一段時間後,慢慢就會找到感覺,接下來可以嘗試着修改一些系統性的一些和應用層比較相似的代碼塊以及編輯塊。

           閱讀系統源碼代碼  一定要記住一點,要有有頭有目的開始 慢慢追溯代碼,如果隨便打開一個文件夾,可能會讓人摸不着頭腦,舉個例子:

          framework/base/ 一些目錄下點開了一些代碼文件,你會發現可能會無從入手,看得懂源碼,但是沒有沒有頭沒有結尾得去看,並不能得到很好的效果。

           在framework/base/core/res/res  定義了很多類似應用層一樣的 資源文件,雖然是系統應用、模塊、框架 的資源集合,但是其實和應用層也沒什麼差別,基本一樣,直接看可能看得懂,但是有什麼用?可能會摸不着頭腦。

分享點3:空餘時間多去了解Android.mk的語法

   2:系統應用結合框架的瞭解 

          怎麼定義系統的框架呢?筆者有着自己的見解,因爲Android源碼極其龐大,模塊異常的多,因此筆者只有需要的時候纔會去深入研究某個模塊,那有的人會問,這模塊是什麼?

          筆者爲什麼要分階段,因爲有部分App工程師可能不會C、C++,這導致了一些 native源碼看不懂,但是此階段基本不會涉及到很多C、C++、JNI。

           舉個例子:

           在App層開發的時候,onKeyDown爲什麼會上報鍵值? 爲什麼Android系統led燈、鍵盤燈 怎麼亮的? 通知欄運行的機制和流程是怎麼樣,當然還有很多。

           有一些小夥伴可能會看一下 pdf、網上搜一些如:

                系統 init、zygote  過程 、Binder 機制、內核的一些機制、Runtime機制、虛擬機相關的、以及系統調度等。。

         那麼筆者非常不建議那些剛轉入framework  還不熟悉的工程師看這些,當然有能力除外,因爲這個是第三階段應該看的,在這第二階段 應該看下 App層與Framework 相關聯的一些東西,讓學習更加的有動力,有自信,過於看一下複雜的東西,可能會導致失去興趣以及動力。

             因此需要學習哪些纔是正確的呢,由於筆者寫出該篇分享文章主要是將做什麼怎麼做體現的可能不會太多,需要小夥伴們自己去思考、琢磨。  

             在framework/base 下有一大堆的java源碼,對了就是它,擼它。你想知道一個通知服務怎麼上報通知的1:百度瞭解 2:搜索源碼文件 [Linux 搜索命令] #:find  /framework/base/   -name  *Notification*    就會出現很多你想要的java文件,接下來就是閱讀源碼了,每個工程師的閱讀源碼能力可能不一致,這邊要說的是,Android 之所以有的很複雜是因爲 Api 調來調去,後面調暈了,在這個過程一定要多debug、log、流程 或者有其他更好的方法去學習沉澱。

              以此類推。 led       ->   1:百度瞭解 2:搜索源碼文件 [Linux 搜索命令]   #:find  /framework/base/   -name  *Led*

 分享點4: PhoneWindowManager.java  可以做很多和App相關的事情,不妨多研究一下它。find 命令 找到它。

        3:系統框架的深入

             有了前面幾部基礎,來到了此階段,那麼,你可以去搜索網上的 framework、HAL 、kernel  知識了,並且去深入研究。

             注:此階段需要有一定的 C、C++、JNI 的知識和了解。

             至於這個階段學什麼,筆者認爲你可以自行安排,熟悉了前兩個階段,後面您自行安排,每個人的方向可能會不一致, 且掌握了前兩個階段這個階段你應該已經掌握到了一些規律和學習方向。

             深入學習框架避免不了 系統編譯環境以及腳本的修改,因此想要更深入的去了解框架,修改框架,定製框架,

那麼一定要熟悉以下幾個點:

             1: 熟悉.mk的用法

             2: shell腳本的熟練

             3: 熟練 Python腳本語言

             6: 熟練Android的框架構建思想

             5: 熟悉安卓Binder系統

             *7: 移植系統、驅動

      分享點4:   find . -type f -exec  grep -Hn --color=auto "您要搜索的內容" {} \;  此命令可以在Linux下快速的搜索文本中的內容,並且高亮顯示。

             Linux(Ubantu,Centos) 命令、系統使用、教程彙總[不定期更新] 

 

第二階段:

       1:Android framework 切入 kernel 需要做一些什麼?

         當你學了一段時間framework後,你可能也掌握了一些其訣竅和規律, framework實在是太龐大了,有時候可能會讓人覺得枯燥無味或者說只有一些項目修改纔會去驅動 定製編碼,因此觀望的瓶頸很快就出現。

         如果你有C、C++ 基礎 ,不妨進軍Linux kernel、Android drivers。 有了編譯Android源代碼的知識,那麼在編譯內核上已經基本會了,知識編譯模塊的命令不一致,一般編譯bootloader->  使用的是[Linux] #:make  aboot  ,kernel -> [Linux] #:make  bootimage, 而編譯system 部分則是 [Linux] #:make systemimage  [Linux] #:mmm  等等。

        筆者喜歡先研究kernel再去研究 bootloader,  因爲驅動可以快速的寫出 HelloWorld!  .

        如何去學習,網上資料零零散散,如果系統性的學習那麼筆者很不建議[如果自學能力強的忽略]。那麼如何系統性得去學習Android驅動?大家可能瞭解了 Android的底層其實是Linux驅動,在這裏筆者建議如果有想了解或者深入的 可以去購買韋東山Linux驅動視頻,Android framework 深入講解的視頻來看。

        筆者建議按照網上的資料以及 視頻教程結合去看。 因爲剛入門的工程師來說,可能找不到方向,而這時候應該要去尋找方向,尋找學習的切入點。韋東山老師的視頻講得很透徹 可以建議去購買學習。

        不管用任何一種方式去學習或者深入研究,必須要有開發板來配合學習,只是一味的觀看源代碼, 不編碼,不編譯   收穫將減大半以上。所以一定要又開發板配套學習,所以一定要又開發板配套學習,所以一定要又開發板配套學習。 重要事情說三遍。 

        bootloader 與kernel 類似。

     

  2:學習方法

      到了這個階段,經過一段時間的沉澱,相信已經基本掌握了系統學習的要領。那麼應該如何去深入學習。這裏再次強調一下,筆者沒有去深入研究分析系統的各個源碼,只是有需要的時候纔會去專研,筆者並不是想一直處於framework或者kernel工作。但是,大致的學習方向,規劃是有的,其實每個人的學習計劃和學習路線學習方法都不一樣,因人而異,筆者這邊只是提出幾點建議:

       1:模塊化學習。系統源碼過於龐大,建議進行模塊化學習,通過模塊化學習再去拓展。

       2:模仿式學習。代碼 ctrl - c , ctrl - v  敲代碼不可少。Android系統框架也很清晰,只是多個同樣測試案例使用了同一套框架導致了代碼"堆積"最後到了巨大龐大的項目。這裏所說的測試案例是真實的程序。那麼不妨參照着他的思路和步驟自己也寫一個案例程序。這是模仿。

      3:真機實操學習。 這裏在強調一遍,一味的看源代碼而不用開發板去實踐的獲得收穫那會是極少的。

  

    目前,安卓不同芯片對應的開發板搭載的系統版本,源碼都存在的一定的差異,可多可少。 有經濟條件可以多買多學多看。但是大體還是離不開整體框架的構建思想。學習過程中可以舉一反三。

            

總結

      只要功夫深,鐵杵磨成針。

            

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章