Linux內核之旅linux
【編者按】咱們常說的智能手機實際上就是手機上加了一個操做系統,那麼大部分人都會跟我同樣不由發問,這個操做系統和咱們接觸更多的電腦上的操做系統同樣嗎。道家雲,看山是山,看山不是山,看山仍是山。這三個境界一樣適用於前邊的問題,你說是否是。
程序員
羅昇陽(博客),1984年出生,2007年畢業於浙江大學計算機系,取得學士學位,2010年畢業於上海交通大學計算機系,取得碩士學位。畢業後一直從事於互聯網軟件開發,而且致力於移動平臺的研究,特別是對Android平臺有深刻的理解和研究。在國內知名IT技術社區CSDN上發表了一百多篇高質量的Android系統原創性文章,而且開設博客專欄——《老羅的Android之旅》。積極與網友交流互動,深受你們喜好,訪問量一直居於前茅。同時,著有《Android系統源代碼情景分析》一書。面試
CSDN:請和你們介紹下你和目前所從事的工做。算法
羅昇陽:我如今正在作一款和手遊相關的Android應用,玩家能夠一邊玩遊戲一邊錄製以及直播。在中國,不管是傳統的PC互聯網,仍是如今的移動互聯網,遊戲都是一個巨大的市場。在手遊超越頁遊追趕端遊的今天,手遊錄製和直播做爲鏈接玩家和玩家、玩家和廠商之間的一個平臺,近年來在國內外都獲得了追棒。在國外,今年5月初的時候,手遊錄製及分享社區Kamcord得到了710萬美圓的A輪融資;到5月中的時候,又傳來Google花10億美圓收購遊戲直播公司Twitch的消息。在國內,愛拍和ShareSDK也發佈了手遊錄製和分享相關的產品。編程
手遊錄製和直播產品吸引個人,除了它的巨大市場以外,還有它的技術含量。坦白說,在Android平臺上,至今尚未一款用戶體驗好的手遊錄製應用。目前Android市場上的手遊錄製應用,不是性能問題,就是穩定性或者兼容性問題。包括在iOS平臺上已經作得至關不錯的Kamcord,在Android平臺上也表現平平。究其緣由有以下三點:瀏覽器
一是Android平臺沒有直接提供獲取遊戲畫面和聲音的接口。安全
二是Android平臺的差別化致使很難找到一個通用的技術方案使其在大部分手機上都能行之有效。在Root過的手機上,雖然可使用截屏接口來獲取遊戲畫面,可是直接使用效率是很低的,難以知足幀率要求。另一個經過讀取Frame Buffer獲取遊戲畫面的方法,在到4.0以後,就更行不通了。服務器
再者,因爲是實時錄製,對視頻編碼的性能要求是很高的。使用軟編碼基本上是不可行的,必需要使用硬編碼。可是使用編碼又要考慮硬件上的適配,不然就很容易產生穩定性和兼容性問題。網絡
爲了解決上述的技術難題,須要用到很底層的Android系統知識,例如Android系統的UI渲染機制和硬編碼等知識。要利用這些知識,沒有深厚的Android功底是很難辦獲得的。因爲我對Android系統有比較深的研究,所以我以爲去作這樣的一個產品是一個頗有意思的挑戰。架構
固然,目前除了作手遊錄製和直播應用以外,還在研究作一些基於Android系統的穿戴式設備,畢竟個人興趣點在於Android系統,並且穿戴式設備也會是將來的方向之一。
CSDN:你是從何時接觸到計算機的,是怎樣走上編程這條道路的?又是在什麼時候開始接觸Android平臺並進行如此深刻研究的呢?
羅昇陽:我接觸計算機的時間是比較晚的,上大學以前,除了在網吧,基本上就沒接觸過電腦了。大學選擇了計算機專業,纔開始真正的接觸電腦。並且我很清楚地刻,大一開學大概一個月的時候,學校要進行計算機文化基礎上機考試,實際上就是考一下Word和Excel的操做。考試前有大概兩週時間讓你有空的時候去機房練習。對於一個之前沒怎麼接觸過計算機、打字都還不利索的孩子來講,果不其然就考掛了。後來補考了一次才及格。
因爲學的是計算機專業,大一的時候就要開始編程的了。一開始學的就是C語言,不像如今不少人一開始學的是都是C#、Java、PHP這些高級又至關易用的語言了。後來才逐漸學習了C++、Java和C#等這些高級語言。剛開始學C語言仍是很痛苦的,龍其學到指針、鏈表這些知識的時候。記得大一上學期的國慶節,還專門花了幾天的時候去啃了鏈表的實現原理。如今回想起來,一開始就選擇學習C語言是對的。由於不管你如今工做用的是什麼語言,若是想要把它背後依靠的平臺吃透,都不可避免地須要瞭解它的底層實現,而這些底層實現基本上都是離不開C/C++。或者換句話說,語言只是一個工具,要理解你的軟件實現原理,關鍵都是要理解軟件背後的計算機系統,而C是最接近計算機系統的語言。所以,我是很是建議有志於從事軟件開發的同窗們,不管你如今、之後工做用的是什麼語言,都必定要學好C/C++。
接觸Android平臺是研究生畢業後工做的事了。正式接觸是2011年年初的時候,當時寫了一個簡單的五子棋遊戲。不過在2010年下半年的時候,就開始計劃要好好研究一下Android系統了。由於瞭解到Android系統是基於Linux內核實現的,因此2010年下半年的時候,主要就是去補Linux內核的基礎知識。其實激發我要去深刻研究Android系統而不是單單是Android應用的動機,是當時在公司作的一款軟件的應用程序框架,是徹底公司的一個團隊自行開發的,沒有采用在學校時接觸的MFC等通用框架。那時候對這套自行開發的應用程序框架很感興趣,但無奈咱們只是業務團隊,平時只是使用這套框架,而沒有機會去深刻研究。
2010年的時候,iOS已經很火了,Android也開始冒出尖尖頭了。因爲Android背後的靠山的Google,並且它的源碼是開放的,所以,就準備去研究一下Android系統的應用程序框架是怎麼實現的。這樣一來能跟上移動潮流,一來也能知足本身的好奇心。今後就一發不可收拾,正式步入Android系統的世界了。
CSDN:你用兩年的時間煉就了深厚的Android內功修養,請問期間的學習之路是怎樣的?有什麼學習的心得和體會可分享?
羅昇陽:那兩年基本是把全部的業餘時間都花在了學習Android上,包括工做日的下班時間、週末、節假日等。因爲是第一次接觸這麼系統又這麼底層的知識,從一開始惡補Linux內核知識,到後來系統地學習Android系統的專用驅動、HAL層和應用程序架構層等知識期間,遇到的困難是可想而知的。以至於在花了兩年的時間,完成Android系統研究的第一階段任務以後,忍不住寫了一篇文章《2012年的Android之旅:夢想、學習、堅持、自信、淡定》總結這段學習經歷。就像文章所說的,那兩年學習Android的心得和體會總結起來就是十個字:夢想、學習、堅持、自信、淡定。因爲篇幅關係,這裏就不一一展開來講了。不過,我最想分享仍是關於堅持這一點。
堅持這兩個字真的是提及來容易作起來難。哪怕是一件很簡單的事情,要求日復一日地堅持去作,恐怕也是很多人作不到的。舉個例子說,鍛鍊身體。咱們不說天天,就說每個星期拿出一個到一個半小時去鍛鍊,又有多少我的能堅持作到的呢?這仍是花時間去作就能完成的,不會遇到諸如學習、工做、生活上的挑戰。因此咱們說堅持就是勝利,是頗有道理的。只要制定好了目標,就必定要下定決心堅持去完成,不管中間遇到什麼樣的困難和挑戰。當堅持變成一種習慣的時候,離目標的實現就不遠了。換句話說,主要你肯堅持,你就會發現:一、你的目標實現了;二、你養成了一種良好的習慣。
常常聽到有人說,太難了,看/學/作不下去了。其實,沒有什麼事情是與生俱來就會的。既然是不會的,學習的過程就確定要付出代價。2010年下半年以前,我平時學習、工做、和娛樂基本上都是在Windows平臺上,第一次學習Linux內核看的是《Linux內核源代碼情景分析》 這本書。看過這本書的人都知道,那基本上就是一本天書。當時我對本身說,不緊要,看一遍不懂,我就再看第二遍、第三遍和第四遍。最後執行的過程是,看過第一遍後,內心只是大概有個譜。接着去找一些相關的經典書籍來繼續看,例如《Linux內核設計與實現》。看完了《Linux內核設計與實現》,回過頭來又接着第二遍看《Linux內核源代碼情景分析》。這下就發現原來一些看不懂的地方如今懂了,可是仍是有其它地方看不懂。因而,又繼續看了《Linux設備驅動程序》和《深刻理解Linux內核》等書。每次以爲有必要的時候,都又從新去看一遍《Linux內核源代碼情景分析》。通過這樣的三四遍折騰以後,最後終於能夠很愉快地看懂《Linux內核源代碼情景分析》了。
固然,除了有毅力去堅持以外,還要懂得堅持的方法。借用馬丁·路德·金的一句話:
If you can’t fly, then run; if you can’t run, then walk; if you can’t walk, then crawl, but whatever you do, you have to keep moving forward。
這句話我以爲重點就是最後三個單詞「keep moving forward」。在堅持的過程當中,你要讓本身以爲本身一直在「keep moving forward」,這樣纔會有堅持下去的動力。換句話說,就是要讓本身在堅持的過程當中看獲得事情又推動了一步,哪怕是一點點的進步。仍是以看書爲例子。只要你天天堅持平均看20頁,一年就能夠看7300頁。打個8折,也有5840頁,也至關於10本書了。10本書看下來,能夠學到的東西是至關多的了。在這個過程當中,天天看20頁書這件事就是推你向前了一步。有人可能以爲天天看20頁書仍是太難了。是的,開始的時候多是有點難。可是,當你堅持一段時間以後,就會發現瞭解的知識變多以後,看書的速度也跟着加快,到時候不要說一天20頁,一天50頁都不是問題。
CSDN:你是《Android系統源代碼情景分析》(試讀地址)一書的做者,這本書是怎樣誕生的?這是你的第一本書,寫書過程當中經歷了怎樣的困難?隨着Andriod的版本更迭,你會出第二版嗎?還有其它著書計劃嗎?
羅昇陽:一開始只是想經過博客記錄本身學習Android系統的過程,並無計劃寫書的。隨着博客的人氣上升,不斷有出版社編輯發出出書的邀請。開始的時候,基本上仍是拒絕的。再到後來,也有很多網友建議把博客整理一下成書出版。在出版社和網友的屢次建議下,也考慮到有些讀者可能更喜歡閱讀紙質書,最終就決定把博客的文章整理成書出版了。
第一次寫書,懷着的是坐臥不安的心情,擔憂能力有限,誤人子弟。書與博客不同,出書包含有出版社、渠道和銷售等成本,所以讀者是不可能免費獲得的。既然讀者要付出錢來購買你的書,那你寫書的時候就得負起責任,例如要保證內容的系統性、完整性和正確性,還有文字表達的通順性,甚至還不能出現錯別字。這與在網上寫博客有很大的區別。寫博客能夠比較隨意一點,漏掉的內容能夠之後再補,錯誤字也能夠立刻就修改過來。
基於面這些緣由,寫書過程經歷的困難是可想而知的。決定寫書以後,一開始並無急着去寫,而是將計劃綱入書裏面的內容都先發表到博客上,也就是我在2011年12月前發表的文章。主要是考慮到先將內容發表出來,讓讀者看到以後能夠幫忙發現BUG以及提建議,這樣能夠幫助提升書的質量。整理博客不是簡單的拷貝粘貼,比我想象中要困難多了。回過頭來再看本身發表過的文字,百分之七八十都要從新表達。並且有些章節,要系統地描述清楚,單靠博客上的文章是遠遠不夠的。例如,在寫Binder那一章時,原覺得在博客寫的一系列文章已經夠完備了,可是發現只是寫了一半不到。而後就拼命地一邊整理已有的內容,而且一邊補新的內容。
在時間上,從開始整理到出版的半年時間裏,除了工做基本就是撲在寫書上了,並且利用的都是工做之餘的時間。沒有周末,沒有節假日,工做日也是常常熬夜到兩三四點。對程序員來講,寫文字其實比寫代碼要累多了,這就是爲何程序員都不喜歡給本身的代碼寫文檔寫註釋的緣由。期間是想過要放棄的,可是已經跟出版社簽訂了合同,怎麼都堅持下去啊。就這樣一路走來,從博客文章整理獲得初稿,又通過三遍逐行逐行的校對,終於完成了三大篇十六章830頁近160萬字的著做。說實話,當時要是再讓我看第四遍的時候,感受都要吐了。
Android版本更新的確是比較快,不過目前是沒有出第二版的計劃了。主要是由於我寫的內容都是很基礎的東西,例如HAL、Binder IPC、Ashmem、Logger,以及四大組件Activity、Service、Broadcast Receiver和Content Provider的實現原理,它們在後來的版本中仍然是保持性當初的設計思想和運行原理的。我更但願的是,讀者看了個人書以後,可以本身去分析Android系統的源碼,這樣之後Android版本更新得再快也不怕了。
至於新書,之前是有計劃的。完成了《Android系統源代碼情景分析》一書以後,我又陸續在博客了發表了UI架構、UI渲染、窗口管理、Dalvik虛擬機、編譯系統、SEAnroid安全機制等一系列的文章。這些內容加起來也能夠有《Android系統源代碼情景分析》這本書那麼厚了。不過寫書是費時費力的事情,並且產出投入比也不高,再加我也不是專職的圖書做家,因此如今也不打算出新書了。可是博客是必定會堅持寫下去的,但願讀者能夠持續關注,而且能夠在博客上與我交流。
CSDN:初學Android的時候,不少人搞不清Android和Java到底有什麼不一樣,你認爲他們之間的區別是什麼呢?另外,Android內核跟linux又有什麼區別?
羅昇陽:實際上,Android是Android,Java是Java。不用Java,用C/C++寫的程序,也同樣能夠在Android上運行。對於這個問題,其實不僅是初學者,對於很多有經驗的開發者,也會認爲作Android應用開發,懂Java就好了。從最近面試的一些人來看,就很明顯地感受到這個問題的廣泛性。不少Android應用開發者只懂得使用Android SDK提供的Java接口來開發東西,可是沒有進一步去學習一些更深層次的東西。
本質上說,Android是一個Linux系統,所以它是基於Linux內核開發的。可是Android與通常的Linux系統不一樣的是,它有着本身的一套獨特的用戶空間運行時,也就是咱們一般說的應用程序框架。舉個例子來講,之前不少基於Linux的嵌入式開發,就是移植一個Linux內核,而後再用Qt做爲應用程序框架,這樣一個系統就跑起來了。所以,將Qt應用程序框架替換爲Android本身的應用程序框架,就獲得了一個現代化的移動操做系統。
在Android應用程序框架中,包含了不少開源工程,例如瀏覽器用的內核WebKit、管理Wi-Fi網絡的wap_supplicant、播放音樂視頻的StageFright等,它們都是使用C/C++來寫的。並且Android系統專用的用來渲染UI的SurfaceFlinger、用來播放聲音的AudioFlinger等,也是用C/C++來寫的。更不用提每個應用程序都要使用到C庫bionic、Dalvik虛擬機等了,它們都是用C/C++來寫的。這些使用C/C++寫的服務,實現了最基本的功能。這些最基本的功能被在Java層的提供的關鍵服務所使用,例如組件管理服務ActivityManagerService、應用程序安裝服務PackageManagerService、網絡鏈接服務ConnectivityService等。最後,Android再封裝了一套基於Java語言的SDK給開發者去使用那些實如今Java層的系統服務。
也就是說:Android系統=Linux內核+Android用戶空間運行時+ Android SDK,而Android用戶空間運行時=C/C++ Runtime Framework + Java Runtime Framework。不少狀況下,咱們調用Android SDK提供的一個API時,這個API調用會交給Java Runtime Framework處理,而Java Runtime Framework又繼續將這個API調用交給C/C++ Runtime Framework處理,最後C/C++ Runtime Framework又有可能接着將這個API調用交給Linux內核來處理。
從上面的調用過程就能夠看出,Java只是位於Android最上面的一層編程接口,而沒有這一層編程接口Android也是能夠正常運行的。咱們知道,Android除了提供SDK外,還提供有NDK。也就是說,咱們徹底能夠不使用SDK,而是經過NDK提供的接口繞過Java Runtime Framework,直接將請求交給C/C++Runtime Framework處理。
至於Android系統使用的Linux內核,其實與傳統的Linux內核並沒有多大區別,甚至能夠當作是同樣的。要說真的區別,就是有兩點。一是Android在傳統的Linux內核中以模塊的形式加入了一些專用的驅動,例如日誌驅動Logger、匿名共享內存驅動Ashmem、進程間通訊驅動Binder。二是Android系統將在傳統的Linux內核實現的硬件驅動程序劃分紅了兩部分,一部分在內核實現,另外一部分在用戶空間實現,也就是咱們常說的硬件抽象層HAL。Android系統之因此要這樣劃分,是出於商業考慮,而不是技術考慮。由於Linux內核使用的GPL許可協議,驅動所有放在內核實現就意味着須要所有開源代碼,而用戶空間使用的是Apaache License,能夠不開源代碼。經過這種方式,就能夠保護廠家的商業利益,由於這些代碼一般都會包含有硬件的相關參數。
CSDN:Android系統層次結構是怎樣的?各個層之間關係是什麼?
羅昇陽:上面也提到了Android系統的層次,詳細一點說,就是:Android = Linux Kernel + C/C++ Runtime Framework + Davik Virtual Machine + Java Runtime Framework + Java SDK。下面咱們再以APK的開發、編譯、安裝和運行來講明這些層次之間的關係。
首先,咱們是在PC上使用Android SDK提供的接口來開發APK,用的Java語言。開發完成以後,使用Java編譯器將源代碼編譯成Java字節碼,也就是帶.class後綴的文件。接下來這些.class再被Android SDK提供的dx工具轉化成Dex字節碼,最後打包在APK裏面的classes.dex文件中。
接着,APK文件在手機上安裝時,Java Runtime Framework裏面的PacakgeManagerService就會對該APK文件進行解析,而且經過Socket IPC通知C/C++ Runtime Framework裏面的installd守護進程對APK裏面的classes.dex文件進行優化,獲得另一個classes.odex文件。
APK安裝完成以後,就能夠運行了。咱們以APK從桌面Launcher啓動的過程爲例說明它的運行過程。當咱們從Launcher點擊應用圖標的時候,Launcher向Java Runtime Framework裏面的ActivityManagerService發送一個啓動應用的請求。ActivityManagerService又經過Socket IPC向C/C++ Runtime Framework裏面的zygote守護進程請求建立一個應用程序進程。這個應用程序進程包含有一個Dalvik虛擬機。應用程序進程建立而且啓動起來以後,就會經過它裏面的Dalvik虛擬機加載前面提到的classes.odex文件。這樣咱們的應用程序就運行起來了。
APK的運行過程是依賴於Dalvik虛擬機的。咱們能夠將它當作是將classes.odex裏面的字節碼解釋成本地機器指令執行。例如,咱們在APK裏面經過FileInputStream或者FileOutputStream打開一個文件的時候,Dalvik虛擬機就會找到C/C++ Runtime Framework裏面的C庫bionic提供的系統接口open,而且經過它來打開指定的文件。
咱們再以應用程序界面的繪製和渲染過程來詳細說明各個層次的關係。首先是應用程序經過SDK提供的UI類向Java Runtime Framework裏面的WindowManagerService申請分配一塊圖形緩衝區。WindowManagerService又是經過Binder IPC向C/C++ Runtime Framework裏面的SurfaceFlinger申請分配圖形緩衝區的。圖形緩衝區實際上不是由SurfaceFlinger分配的,而是由顯示系統分配的,可能在顯存裏面,也有可能在GPU裏面。這時候SurfaceFlinger就要經過HAL層次Gralloc模塊向Kernel裏面的顯卡或者GPU驅動申請分配真正的圖形緩衝區。HAL層能夠看做是運行在C/C++ Runtime Framework中。
應用程序得經過上述方式獲得繪製UI所須要的圖形緩衝區以後,就開始繪製本身的UI了。假設應用程序使用的是硬件繪製方式,也就是經過C/C++ Runtime Framework裏面的OpenGL來繪製。這時候SDK的UI類的與繪製相關的函數調用經過Dalvik虛擬機都轉化成了C/C++ Runtime Framework裏面的OpenGL操做。
應用程序UI繪製完成以後,結果就保存上述的圖形緩衝區中。這時候若是要將該圖形緩衝區渲染到手機屏幕上,那麼還須要經過Binder IPC將該圖形緩衝區發送給C/C++ Runtime Framework裏面的SurfaceFlinger。SurfaceFlinger經過使用OpenGL或者HWComposer將全部請求要渲染到手機屏幕上的圖形緩衝區合成以後,獲得一個主圖形緩衝區。最後這個圖形緩衝區又會被SurfaceFlinger提交給Kernel的顯卡驅動,而且在手機屏幕上進行顯示。
上面描述的就是Android系統各個層次的調用關係。總的來講,應用程序運行在Dalvik虛擬機上,而且經過SDK使用Java Runtime Framework裏面的服務,而Java Runtime Framework裏面的服務又經過C/C++ Runtime Framework裏面的服務來實現本身的功能,最後C/C++ Runtime Framework裏面的服務又會在須要的時候請求Kernel裏面的模塊或者驅動來爲本身服務。
CSDN:Andriod能夠說是開源的代名詞,一些開發者爲了保護本身的成果進行加密,而另外一些開發者爲了學習,須要進行APK反編譯,能夠分享下您對加密和反編譯的見解嗎?
羅昇陽:嚴格來講,Android系統是開放不是開源。Linux內核纔是嚴格意義上的開源。只要是運行在Linux內核裏面的代碼,均可以要求做者將代碼開源出來。可是運行在Android系統用戶空間的代碼,做者就不須要將它們開源出來了。這些代碼包括廠商對Android官方源碼的修改,以及本身增長的代碼,還有第三方爲之開發的APK代碼等。這是因爲Linux內核使用的是GPL許可協議,而Android系統的用戶空間代碼使用的Apache許可協議。
我以爲不管是開發者爲了保護本身的成果而對APK進行加密,仍是另外一些開發者爲了學習而反編譯別人的APK,都是無可厚非的。固然前提是不要利用這些技術去作壞事,不然的話,就是違反法律的事情了。加密和反編譯其實是一種技術競爭關係。咱們都知道,競爭實際上是能夠推動技術進步的,而技術進步的最終結果對用戶是有好處的。
我在這兩個講《Android安全機制》和《APK防反編譯技術》的PPT中,有描述過經過DEX和SO加殼、添加非法指令、隱藏敏感代碼和僞APK加密技術等辦法來保護代碼的方法。然而,再厲害的保護技術,只要計算機知識牢固,而且有足夠的耐心,再加上一些工具,例如apktool和ida,都是夠破解的。固然,在別人破解了你如今的保護技術以後,你能夠再發明另外的技術來保護本身的代碼。這就是技術競爭,比的是各自的技術水平。
CSDN:深刻理解框架層,須要具有哪些知識?對於開發應用具體有什麼好處?而開發者在學習這一過程當中應注意哪些問題?
羅昇陽:從上面對Android系統的描述能夠知道,要學入去學習Android系統的框架,須要具有的知識是很多的。
從語言層面來講,須要掌握C、C++、Java,甚至還有彙編。
從系統層面來講,須要有Linux內核基礎,包括進程管理、內存管理、文件系統等,還須要掌握Android的HAL、C/C++ Runtime Framework、Java Runtime Framework和Davivk等。
雖然應用開發者平時不用接觸系統方面的東西,可是若是可以深刻理解Android的框架層,好處是不言而喻的。
首先,能夠提升能力和拓寬眼界。由於要看得懂Android系統的代碼,要求瞭解不少知識。要了解這麼多的知識,又須要不斷地去學習。在學習的過程當中,能力和眼界就會天然獲得提升和拓寬。
其次,能夠正確地使用SDK接口。學習SDK接口,咱們通常是經過閱讀SDK文檔。可是這些SDK文檔只是告訴你它們是怎麼用的,沒有告訴你它們是怎麼實現的。若是咱們既知道一個SDK接口是怎麼用的,又知道它是怎麼實現的,那麼用起來確定會得心應用不少。並且在使用出錯的時候,也能迅速地經過檢查它的實現代碼來定位緣由。
再者,能夠有效地解決BUG。當程序運行出錯的時候,系統除了會輸出異常信息或者Crash信息以外,一般還有伴隨着一些錯誤日誌輸出。每每這些系統輸出的錯誤日誌包含很豐富的信息,告訴究竟是哪些地方出錯了。可是這些錯誤日誌是由系統輸出的,它們的含義以及輸出條件都是由系統定義的。這時候若是要理解究竟是什麼地方出錯了,那就得對系統有必定的理解,甚至須要找到輸出這些日誌的系統代碼來閱讀一下。
總之就是技多不壓身,學到的東西都是本身的,之後靠這些技術賺到的錢也是本身的。可是前面講到,要學入理解Android系統,須要具有的知識是不少的。基於這個緣由,應用開發者最須要注意的問題就是不要被這個問題嚇退。實際上是沒有人與生俱來就具有這些知識的,並且知識是無究無盡的,活到老就能夠學到老。因此必定要堅持學習,一點一滴的積累,哪些不懂就補哪裏。開始學慢一點沒有關係,等積累到必定程度的時候,就會發現本身的學習能力呈加速度趨勢。
CSDN:移動互聯網現在發展得如火如荼,Android在其中佔居着重要的角色,其發展衆說紛紜, 你如何看待Android的將來?
羅昇陽:Android的發展問題,無非就是與iOS相比,孰優孰劣的問題。目前在移動互聯網上,還找不到第三個能夠與Android和iOS抗衡的系統。Android與iOS相比,不少人無非就是以爲:
1. Android UI不夠流暢;
2. Android不夠安全;
3. Android更耗電;
4. Android兼容性差。
剛開始的時候,Android UI與iOS相比,流暢性的確是差不少。一方面是由於Android手機良莠不齊,有些在硬件配置上確實不如iOS。另外一方面確實是Android系統自身的問題。可是咱們看到自3.0以來,Android就一直在增強UI流暢性進行努力。Android在3.0在應用程序進程這一側,容許使用硬件繪製UI。在4.1的時候,又經過Project Butter計劃,極大地提升了UI的流暢性。到了L版本,又用ART代替了Dalvik,這意味着應用程序運行時執行的是本地機器指令,而再也不是虛擬機機指令,性能將獲得極大的提高。總之,目前在同等硬件配置下,Android的UI流暢性與iOS相比,差距是愈來愈小了。咱們期待ART代替Dalvik以後,二者能夠不相伯仲。
關於安全問題,iOS也有自身的安全問題,例如,每次iOS版本升級後,不也是有人很快就發佈了越獄工具嗎?同時咱們也看到,Android在4.3版本,引進了SEAndroid,用來增強其安全性。SEAndroid是美國國家安全局(NSA)在SELinux的基礎上專門爲Android系統開發的,用來保證系統即便在被root的狀況下,也能最大限度地保護用戶手機的安全。另外一方面咱們也看到,因爲Android系統是開放的,有不少第三方的安全公司,例如Bluebox,積極地幫忙發現漏洞,以即可以及時進行修復。
加密算法有一個Kerckhoffs原則:祕密寓於密鑰。意思就是說一個密碼系統的安全性,應該僅僅依靠「密鑰沒有泄漏」這個前提。即便整個系統落到了敵人的手裏,敵人了整個系統的全部細節,可是若是敵人不知道密鑰,你的傳輸仍是安全的。不管是在戰爭仍是和平時期,不能把保密的但願寄於系統/算法的保密性,由於機械的能夠拆解,軟件的能夠看彙編。在這一點上,非公開算法和公開算法的區別就體現出來了:公開算法受全世界的密碼學者研究,經受得考驗;非公開算法只有除了做者外別人都不知道,可能有很好的***可是做者沒有發現。我想因爲Android系統是開源的,而iOS系統是閉源的,它們的安全性之間的比較能夠類比於公開和非公開的加密算法安全性比較。
至於Android的耗電問題,很大程度是由應用程序引發的。因爲某些緣由,Google官方提供的統一推送服務不能在國內使用,致使了每個須要網絡推送的應用程序都自已在後臺啓用了一個服務,定時地檢查服務器有沒有新的通知。即便是手機已經休眠了,也會對其進行喚醒進行檢查。這就形成了電量很是大的消耗。iOS有統一的推送服務,而且不容許應用本身設計一套推送服務,所以就能夠保證電池的優化使用。爲了必定程度上解決這個問題,Android在L版本提供了Job Scheduler服務,用來對齊應用對設備的喚醒,以達到優化電池使用的目的。
至於Android的兼容性,是因爲Android系統的開放性形成的。各個廠商均可以將Android源碼拿過來進行修改,而且跑在硬件配置各不相同的手機上,所以就形成在一個手機上運行得很好的程序,到了另一個手機上就可能會出現問題。
歸結來說,Android的耗電問題和兼容性問題,很大程度都是因爲Android的開放性致使的。然而,Android的開放性也正是它的優勢所在。回想起上個世紀末期,蘋果計算機與IBM兼容PC之爭,咱們就會發現,IBM兼容PC正是靠開放性戰勝了蘋果計算機。固然,今時不一樣往日,今天依然閉源的iOS和開放的Android,二者除了在手機以外,在車載、穿戴式設備、智能家居方面,也都展開全面的競爭,鹿死誰人還不知。可是,咱們如今看到的是,不少創業者,想要作本身的智能設備時,第一時間想到的確定是使用Android系統。這說明Android系統有羣衆基礎。咱們指望衆人拾柴火焰高,Android的發展愈來愈好。
CSDN:對於Android開發的學習者,他們如何在競爭如此激烈的移動互聯網環境中提高本身的核心競爭力呢?另外,你能推薦一些書給他們嗎?
羅昇陽:要在激烈的移動互聯網環境中提高本身的核心競爭力,關鍵仍是要提到本身的技術水平,最佳的途經就是持續的不斷學習。學習既要有廣度,又要有深度。本身感興趣的知識,必定要深刻去研究。其它相關的知識,也要嘗試去有必定的瞭解。
關於學習這個話題,有些人以爲如今用不到的東西就沒有必要去學習,不然就太浪費時間了。其實,不少東西等到要用到的時候再去學,就太遲了。要知道,咱們經過學習用到的東西,雖然不會直接反應在咱們如今工做的內容上,可是也會潛默移化地響應着咱們思考方式,把咱們往好的方向推進。還有的就是,咱們學的全部東西都不會白白浪費的,總有一天都會派上用場的,特別是在當今十年河東十年河西的科技時代。十年前,火的是傳統互聯網;十年後,輪到移動互聯網上場;再過五年或者十年呢?誰都不知道會怎麼樣,可是隻要咱們有技術在手,就能積極擁抱變化。畢竟從技術層面講,不管時代怎麼變化,核心的東西都相通的。
要推薦的書,我在《那兩年煉就的Android內功修養》這篇文章中有提到,這裏再列一下出來:
語言類:
《深度探索C++對象模型》,對應的英文版是《Inside C+++ Object Model》
程序編譯、連接、加載類:
《連接器和加載器》,對應的英文版是《Linker and Loader》
《程序員的自我修養:連接、裝載和庫》
操做系統類:
《Linux內核設計與實現》,對應的英文版是《Linux Kernel Development》
《深刻理解Linux內核》,對應的英文版是《Understanding the Linux Kernel》
《深刻Linux內核架構》,對應的英文版是《Professional Linux Kernel Architecture》
《Linux內核源代碼情景分析》
網絡類:
《Linux網絡體系結構:Linux內核中網絡協議的設計與實現》,對應的英文版是《The Linux Networking Architecture: Design and Implementation of Network Protocols in the Linux Kernel》
《深刻理解LINUX網絡技術內幕》,對應的英文版是《 Understanding Linux Network Internals》
設備驅動類:
《Linux設備驅動程序》,對應的英文版是《Linux Device Drivers》
《精通Linux設備驅動程序開發》,對應的英文版是《Essential Linux Device Drivers》
虛擬機類:
《Java SE 7虛擬機規範》
《深刻Java虛擬機》,對應的英文版是《Inside the Java Virtual Machine》
《Oracle JRockit: The Definitive Guide》
嵌入式類:
《嵌入式Linux開發》,對應的英文版是《Embedded Linux Primer》
《構建嵌入式Linux系統》,對應的英文版是《Building Embedded Linux Systems》
ARM體系架構類:
《ARM嵌入式系統開發:軟件設計與優化》,對應的英文版是《ARM System Developer's Guide: Designing and Optimizing System Software》
綜合類:
《深刻理解計算機系統》,對應的英文版是《Computer Systems: A Programmer's Perspective》
同時,我本身也是處於不斷的學習中,平時也會看其它比較多的書,你們有興趣的話,能夠關注個人新浪微博(@羅昇陽),上面有不定時的推薦。
CSDN:你在CSDN的社區中具備着極高的人氣,博客專欄「老羅的Android之旅」受到你們的追捧,當初你爲什麼選擇寫博客?寫博客給你帶來了什麼好處?
羅昇陽:當初選擇寫博客,是寫給本身看的,當筆記用。不然若是什麼都不寫的話,研究過的東西很快就忘記了。直到如今,在須要的時候,我都會去翻本身的博客。隨着博客讀者愈來愈多,博客就再也不是給本身當筆記用了,仍是一個用來學習交流分享知識,以及結識志同道合的朋友的場所。
不過,我以爲最重要的是,經過發表博客文章,可讓對我Android的研究更加嚴謹、更加詳細、更加系統。由於天天這麼多讀者瀏覽你的文章,你就必需要保證文章的質量,不然的話就會誤人子弟,也會毀了本身的名聲。爲了寫出有質量的文章,就必需要嚴謹、詳細和系統地去研究Android系統的代碼。所以,寫博客和研究Android是一個相互促進的過程。
CSDN:你是何時接觸CSDN的?它對你學習和工做都帶來哪些影響?同時,對CSDN有什麼建議?
羅昇陽:在寫博客以前,實際上是比較少接觸CSDN。2011年6月決定要經過博客來記錄本身研究Android的歷程時,也嘗試過找其它的博客網站來寫文章。最後發現CSDN文章貼的代碼顯示格式用戶體驗挺好的。因而就決定使用CSDN博客了。
CSDN對學習和工做的影響,最主要的就是它讓我用嚴謹、詳細、系統的方法去研究Android,從而也使得我對Android系統的理解更加深刻。
對CSDN的建議,就是但願CSDN能夠增強穩定性,之前時不時都會出現訪問不了的狀況,不過最近半年狀況好像是好一些了。另一個是增強對移動端的用戶體驗。我看到最近CSDN增長了對移動端的支持,不過在瀏覽我的博客時,看不到博主的相關信息,例如瀏覽量、積分、排名和評論等。有時候想看看有沒有新的評論須要回覆,看不到就麻煩的,沒法與讀者進行交流,並且又不能切換回PC端模式。