Android內功修養

yangxi_001發表於2013-11-20

經過兩年的時間,終於完成對Android系統的研究了。Android是一個博大精深的系統,老羅不敢說自己精通了(事實上最討厭的就是說自己精通神馬神馬的了,或者說企業說要招聘精通神馬神馬的人才),但是至少可以說打通了整個Android系統,從最上面的應用層,一直到最下面的Linux核心,煉就的是一種內功修養。這篇文章和大家一起分享這兩年研究Android系統的歷程,以此感謝大家一直以來的支援和鼓勵。

        以下是本文的提綱:

        1. 理念

        2. 里程碑

        3. 看過的書

        4. 研究過的內容

        5. 將來要做的事情

        它們涵蓋了老羅這兩年一直想要和大家分享的內容。好了,不說廢話了,直入主題。

        一. 理念

        這裡說的理念是說應該帶什麼樣的心態去研究一個系統。古人說書中自的顏如玉,書中自有黃金屋,我想說程式碼裡也有顏如玉和黃金屋,所以老羅希望大家都能“Read The Fucking Source Code”。再者,對於優秀的開源專案來說,不去讀一下它的原始碼,簡直就是暴殄天物啊。那麼,讀程式碼有什麼好處呢?太多了,除了可以學到別人的優秀程式碼、架構之外,最重要的是,我們能從中找到答案,從而可以解決自己專案上的燃眉之急。

        我們在專案中碰到問題的時候,通常第一反應都是到網上去搜尋答案。但是有時候有些問題,網路並不能給出滿意的答案。這時候就千萬不要忘了你所擁有的一個大招——從程式碼中找答案!當然,從程式碼中找答案說起來是輕鬆,但是等到直正去找時,可能就會發現雲裡霧裡,根本不知道那些程式碼在說什麼東東,甚至連自己想要看的原始碼檔案都不知道在哪裡。這就要求平時就要養成讀程式碼的習慣,不要臨時抱佛腳。有時候臨時抱佛腳是能解決問題,但是千萬不能抱著這種僥倖心裡,掌握一門技術還是需要踏踏實實地一步一步走。

        胡克其實在牛頓之前,就發現了萬有引力定律,並且推匯出了正確的公式。但由於數學不好,他只能勉強解釋行星繞日的圓周運動,而沒有認識到支配天體執行的力量是“萬有”的。後來數學狂人牛頓用微積分圓滿地解決了胡克的問題,並且把他提出的力學三條基本定律推廣到了星系空間,改變了自從亞里士多德以來公認的天地不一的舊觀點,被科學界奉為偉大的發現。胡克大怒,指責牛頓剽竊了他的成果。牛頓尖酸刻薄的回敬:是啊,我他媽還真是站在巨人的肩膀上呢!

        我們有理由相信像牛頓、賈伯斯之類的狂人,不用站在巨人的肩膀上也能取得矚目的成就。但是,我們不是牛頓,也不是賈伯斯,所以在看程式碼之前,還是找一些前人總結的資料來看看吧。拿Android系統來說,你在至少得懂點Linux核心基礎吧!所以在看Android原始碼之前,先找些Linux核心的經典書籍來看看吧,騷年!後面老羅會推薦一些書籍給大家。

        另外,我們知道,現在的網際網路產品,講究的是快速迭代。Android系統自第一個版本釋出以來,到現在已經經歷了很多版本呢?那麼我們應該如何去選擇版本來閱讀呢?一般來說,就是選擇最新的版本來閱讀了。不過隨著又有新版本的原始碼的釋出,我們所看的原始碼就會變成舊版本。這時候心裡就會比較糾結:是應該繼續看舊的程式碼,還是去追新版本的程式碼呢?就當是看連續劇,一下子跳到前面去,可能就不知道講什麼了。其實版本就算更新得再快,基礎的東西也是不會輕易變化的。我們看程式碼時,要抱著的一個目的就是弄懂它的骨架和脈絡。畢竟對於一個系統來說,它是有很多細節的,我們無法在短時間把它們都完全吃透。但是主要我們掌握了它的骨架和脈絡,以後無論是要了解它的什麼細節,都可以很輕輕地找到相關的原始檔,並且可以很容易進入主題。

        坦白說,對於Android系統,很多細節我也不瞭解。所以有時候你們可以看到,在部落格文章後面的評論上,有些同學問的一些比較具體的問題,我是沒有回覆的。一來是我不懂,二來是我也沒有時間去幫這些同學去扒程式碼來看。這也是在文章一開頭,我就說自己沒有精通Android系統的原因。但是請相信,主要你熟悉Android系統的程式碼,並且有出現問題的現場,順藤摸瓜跟著程式碼走下去,並且多一點耐心和細心,是可以解決問題的!

        關於Android版本的問題,相信大家都知道我現在的文章都是基於2.3來寫的。很多同學都說我out了,現在都4.2了,甚至4.3或者5.0都要出來了,還在看2.3。我想說的是,主要你掌握了它的骨架和脈絡,無論版本上怎麼變化,原理都是一樣的,這就是以不變應萬變之道。因此,我就一直堅持研究2.3,這樣可以使得前前後後研究的東西更連貫一致,避免分散了自己的精力。如果還有疑問的話,後面我講到Android的UI架構時,就會簡單對比一下4.2和2.3的不同,其實就會發現,基本原理還是一樣的!

        說到Android系統的骨架和脈絡,也有同學抱怨我的文章裡面太多程式碼細節了,他們希望我可以抽象一下,用高度概括的語言或者影象來勾勒出每一個模組的輪廓。我想說的是,如果你不看程式碼,不瞭解細節,即使我能夠用概括的語言或者影象來勾勒出這樣的輪廓出來,也許這個輪廓只有我才能看得懂。

        我在真正開始看Android系統的原始碼之前,也是有這樣的想法,希望能有一張圖來清楚地告訴我Android系統的輪廓,例如,HAL為什麼要將驅動劃分成使用者空間和核心空間兩部分,為什麼說Binder是所有IPC機制效率最高的。我確實是從網上得到抽象的資料來解釋這兩個問題,但是這些資料對我來說,還是太抽象了,以至於我有似懂非懂的感覺,實際上就是不懂!就是因為這樣,激發了我要從程式碼中找答案的念頭!現在當我回過頭來這些所謂抽象的輪廓時,我就清楚地知道它講的是什麼了。

        所以古人云“天將降大任於斯人也,必先苦其心志,勞其筋骨,餓其體膚”是有道理的,因為只有親身經歷過一些磨難後得到的東西才是真實的!

        好了,關於理念的問題,就完了,這裡再做一下總結:

        1. 從程式碼中找答案——Read The Fucking Source Code。

        2. 以不變應萬變——堅持看一個版本的程式碼直至理清它的骨架和脈絡。

        二. 里程碑

        研究Android 2.3期間,主要是經歷了以下五個時間點,如圖1所示:


圖1 研究Android 2.3的里程碑

         從2011年06月21日第一篇部落格文章開始,到2013年06月03日結束對Android 2.3的研究,一共是差不多兩年的時間,一個從無到有的過程。其中,最痛苦的莫過於是2011年12月下旬到2012年06月12日這6個多月的時間裡面,整理了2011年12月下旬前的所有部落格文章,形成了《Android系統原始碼情景分析》一書,並且最終在2012年10月下旬正式上市。

        總的來說,就是在兩年的時間裡面,獲得了以下的兩個產出: 

        1. 《老羅的Android之旅》部落格專欄93篇文章,1857224次訪問,4156條評論,13440積分,排名154。

        2. 《Android系統原始碼情景分析》一書3大篇16章,830頁,1570000字。

        以上產出除了能幫助到廣大的網友之外,也讓自己理清了Android系統的骨架和脈絡。這些骨架和脈絡接下來再總結。2013年06月03日之後,將何去何從?接下來老羅也會簡單說明。

        三. 看過的書 

        在2011年06月21日開始寫部落格之前,其實已經看過不少的書。在2011年06月21日之後,也一邊寫部落格一邊看過不少的書。這個書單很長,下面我主要分類列出一些主要的和經典的。

        語言:

        《深度探索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》

        上面介紹的這些書,都是屬於進階級別的,所以要求要有一定的語言基礎以及作業系統基礎。此外,對於看書,老羅有一些觀點,供大家參考:

        1. 書不是要用的時候才去看的,要養成經常看書、終身學習的習慣。

        2. 不要只看與目前自己工作相關的書,IT技術日新月異,三五年河東,三五年河西。

        3. 書看得多了,就會越看越快,學習新的東西時也越容易進入狀態。

        對於Android應用開發,力推官方文件:

        http://developer.android.com/training/index.html

        http://developer.android.com/guide/components/index.html

        http://developer.android.com/tools/index.html

        四. 研究過的內容

        整個部落格的內容看似鬆散,實際上都是有組織有計劃的,目標是打通整個Android系統,從最上面的應用層,到最下面的Linux核心層。簡單來說,部落格的所有文章可以劃分為“三橫三縱”,如圖2所示:


圖2 Android系統研究之“三橫三縱”

        接下來,老羅就分別描述這三條橫線和縱線,並且給出對應的部落格文章連結。

        1. 準備 -- Preparation -- 橫線

        主要就是:

       (1)通過閱讀相關的書籍來了解Linux核心和Android應用基礎知識

         Android學習啟動篇

       (2)搭建好Android原始碼環境

         在Ubuntu上下載、編譯和安裝Android最新原始碼

         在Ubuntu上下載、編譯和安裝Android最新核心原始碼(Linux Kernel)

         如何單獨編譯Android原始碼中的模組

         製作可獨立分發的Android模擬器

       (3)Android系統有很多C++程式碼,這些C++程式碼用到了很多智慧指標,因此有必要了解一下Android系統在C/C++ Runtime Framework中提供的智慧指標

         Android系統的智慧指標(輕量級指標、強指標和弱指標)的實現原理分析

         2. 專用驅動 -- Proprietary Drivers -- 橫線

         這些專用驅動就是指Logger、Binder和Ashmem,它們整個Android系統的基石:

        (1)Logger

          淺談Android系統開發中LOG的使用

         Android日誌系統驅動程式Logger原始碼分析

         Android應用程式框架層和系統執行庫層日誌系統原始碼分析

         Android日誌系統Logcat原始碼簡要分析

        (2)Binder

          Android程式間通訊(IPC)機制Binder簡要介紹和學習計劃

         淺談Service Manager成為Android程式間通訊(IPC)機制Binder守護程式之路

         淺談Android系統程式間通訊(IPC)機制Binder中的Server和Client獲得Service Manager介面之路

         Android系統程式間通訊(IPC)機制Binder中的Server啟動過程原始碼分析

         Android系統程式間通訊(IPC)機制Binder中的Client獲得Server遠端介面過程原始碼分析

         Android系統程式間通訊Binder機制在應用程式框架層的Java介面原始碼分析

        (3)Ashmem

          Android系統匿名共享記憶體Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃

          Android系統匿名共享記憶體Ashmem(Anonymous Shared Memory)驅動程式原始碼分析

          Android系統匿名共享記憶體Ashmem(Anonymous Shared Memory)在程式間共享的原理分析

          Android系統匿名共享記憶體(Anonymous Shared Memory)C++呼叫介面分析

        3. 硬體抽象層 -- HAL -- 縱線

        硬體抽層象最適合用作Android系統的學習入口,它從下到上涉及到了Android系統的各個層次:

         Android硬體抽象層(HAL)概要介紹和學習計劃

         在Ubuntu上為Android系統編寫Linux核心驅動程式

         在Ubuntu上為Android系統內建C可執行程式測試Linux核心驅動程式

         在Ubuntu上為Android增加硬體抽象層(HAL)模組訪問Linux核心驅動程式

         在Ubuntu為Android硬體抽象層(HAL)模組編寫JNI方法提供Java訪問硬體服務介面

         在Ubuntu上為Android系統的Application Frameworks層增加硬體訪問服務

         在Ubuntu上為Android系統內建Java應用程式測試Application Frameworks層的硬體服務

        4. 應用程式元件 -- Application Component -- 縱線

        應用程式元件是Android系統的核心,為開發者提供了貼心的服務。應用程式元件有四種,分別是Activity、Service、Broadcast Receiver和Content Provider。圍繞應用程式元件,又有應用程式程式、訊息迴圈和安裝三個相關模組。

       (1)Activity

         Android應用程式的Activity啟動過程簡要介紹和學習計劃

         Android應用程式啟動過程原始碼分析

         Android應用程式內部啟動Activity過程(startActivity)的原始碼分析

         Android應用程式在新的程式中啟動新的Activity的方法和過程分析

         解開Android應用程式元件Activity的"singleTask"之謎

       (2)Service

         Android系統在新程式中啟動自定義服務過程(startService)的原理分析

         Android應用程式繫結服務(bindService)的過程原始碼分析

       (3)Broadcast Receiver

         Android系統中的廣播(Broadcast)機制簡要介紹和學習計劃

         Android應用程式註冊廣播接收器(registerReceiver)的過程分析

         Android應用程式傳送廣播(sendBroadcast)的過程分析

       (4)Content Provider

         Android應用程式元件Content Provider簡要介紹和學習計劃

         Android應用程式元件Content Provider應用例項

         Android應用程式元件Content Provider的啟動過程原始碼分析

         Android應用程式元件Content Provider在應用程式之間共享資料的原理分析

         Android應用程式元件Content Provider的共享資料更新通知機制分析

       (5)程式

         Android系統程式Zygote啟動過程的原始碼分析

         Android應用程式程式啟動過程的原始碼分析

       (6)訊息迴圈

         Android應用程式訊息處理機制(Looper、Handler)分析

         Android應用程式鍵盤(Keyboard)訊息處理機制分析

         Android應用程式執行緒訊息迴圈模型分析

       (7)安裝

         Android應用程式安裝過程原始碼分析

         Android系統預設Home應用程式(Launcher)的啟動過程原始碼分析

        5. 使用者介面架構 -- UI -- 縱線

        大家對老羅現在還在寫Android 2.3的UI架構意見最大,認為已經過時了。老羅認為持有這種觀點的人,都是沒有經過認真思考的。老羅承認,從Android 4.0開始,UI部分發生了比較大的變化。但是請注意,這些變化都是在Android  2.3的UI架構基礎之上進行的,也就是說,Android  2.3的UI架構並沒有過時。你不能說Android 4.0在Android  2.3之上增加了一些feature,就說Android  2.3過時了。

        下面這張是從Android官網拿過來的最新UI渲染流程圖,也就是4.2的UI渲染流程圖


圖2 Android 4.2的UI渲染流程

        從這張圖可以看出關於Android的UI架構的三條主線:

      (1)每一個Window的Surface都怎樣渲染的?不管怎麼樣,最後渲染出來的都是一個Buffer,交給SurfaceFlinger合成到Display上。

      (2)SurfaceFlinger是怎樣合成每一個Window的Surface的?

      (3)WindowManamgerService是怎麼樣管理Window的? 

        第(1)和第(2)兩個點在2.3和4.2之間有變化,主要是因為增加了GPU的支援,具體就表現為Window的Surface在渲染的時候使用了GPU,而SurfaceFlinger在合成每一個Window的Surface的時候,也使用了GPU或者Overlay和Blitter這些硬體加速,但是主體流程都沒有變,也就是說,Window的Surface渲染好之後,最終依然是交給SurfaceFlinger來合成。此外,雖然我還沒有開始看4.2的程式碼,但是可以看得出,4.2裡面的HWComposer,只不過是封裝和抽象了2.3就有的Overlay和Blitter,而SurfaceTexture的作用與2.3的SurfaceComposerClient、SurfaceControl也是類似的。第(3)點基本上就沒有什麼變化,除非以後要支援多視窗。

        通過上述對比,只想強調一點:Android 2.3的UI架構並沒有過時,是值得去研究的,並且在2.3的基礎上去研究4.2的UI架構,會更有幫助。

        仁者見仁,智者見智,Android 2.3的UI架構的說明就到此為止,接下來它的分析路線,都是圍繞上述三個點來進行的。

        首先是以開機動畫為切入點,瞭解Linux核心裡面的驅動:

        Android系統的開機畫面顯示過程分析

        FB驅動抽象了顯示卡,上面的使用者空間程式就是通過它來顯示UI的。

        HAL層的Gralloc模組對FB驅動進行了封裝,以方便SurfaceFlinger對它進行訪問:

        Android幀緩衝區(Frame Buffer)硬體抽象層(HAL)模組Gralloc的實現原理分析

        SurfaceFlinger負責合成各個應用程式視窗的UI,也就是將各個視窗的UI合成,並且通過FB顯示在螢幕上。在對SurfaceFlinger進行分析之前,我們首先了解應用程式是如何使用的它的:

        Android應用程式與SurfaceFlinger服務的關係概述和學習計劃

        Android應用程式與SurfaceFlinger服務的連線過程分析

        Android應用程式與SurfaceFlinger服務之間的共享UI後設資料(SharedClient)的建立過程分析

        Android應用程式請求SurfaceFlinger服務建立Surface的過程分析

        Android應用程式請求SurfaceFlinger服務渲染Surface的過程分析

        萬事俱備,可以開始分析SurfaceFlinger了:

        Android系統Surface機制的SurfaceFlinger服務簡要介紹和學習計劃

        Android系統Surface機制的SurfaceFlinger服務的啟動過程分析

        Android系統Surface機制的SurfaceFlinger服務對幀緩衝區(Frame Buffer)的管理分析

        Android系統Surface機制的SurfaceFlinger服務的執行緒模型分析

        Android系統Surface機制的SurfaceFlinger服務渲染應用程式UI的過程分析

        SurfaceFlinger操作的物件是應用程式視窗,因此,我們要掌握應用程式視窗的組成:

        Android應用程式視窗(Activity)實現框架簡要介紹和學習計劃

        Android應用程式視窗(Activity)的執行上下文環境(Context)的建立過程分析

        Android應用程式視窗(Activity)的視窗物件(Window)的建立過程分析

        Android應用程式視窗(Activity)的檢視物件(View)的建立過程分析

        Android應用程式視窗(Activity)與WindowManagerService服務的連線過程分析

        Android應用程式視窗(Activity)的繪圖表面(Surface)的建立過程分析

        Android應用程式視窗(Activity)的測量(Measure)、佈局(Layout)和繪製(Draw)過程分析

        應用程式視窗是由WindowManagerService進行管理的,並且也是WindowManagerService負責提供視窗資訊給SurfaceFlinger的,因此,我們最後分析WindowManagerService:

        Android視窗管理服務WindowManagerService的簡要介紹和學習計劃

        Android視窗管理服務WindowManagerService計算Activity視窗大小的過程分析

        Android視窗管理服務WindowManagerService對視窗的組織方式分析

        Android視窗管理服務WindowManagerService對輸入法視窗(Input Method Window)的管理分析

        Android視窗管理服務WindowManagerService對桌布視窗(Wallpaper Window)的管理分析

        Android視窗管理服務WindowManagerService計算視窗Z軸位置的過程分析

        Android視窗管理服務WindowManagerService顯示Activity元件的啟動視窗(Starting Window)的過程分析

        Android視窗管理服務WindowManagerService切換Activity視窗(App Transition)的過程分析

        Android視窗管理服務WindowManagerService顯示視窗動畫的原理分析

        上述內容都研究清楚之後,Android系統的UI架構的骨架就清晰了。但是前面所研究的應用程式視窗還是太抽象了,我們有必要研究一下那些組成應用程式視窗內容的UI控制元件是怎麼實現的,以TextView和SurfaceView為代表:

        Android控制元件TextView的實現原理分析

        Android檢視SurfaceView的實現原理分析

        最後,分析Android系統的UI架構,怎能不提它的資源管理框架?它有效地分離了程式碼和UI:

        Android資源管理框架(Asset Manager)簡要介紹和學習計劃

        Android應用程式資源的編譯和打包過程分析

        Android應用程式資源管理器(Asset Manager)的建立過程分析

        Android應用程式資源的查詢過程分析

        分析這裡,Android系統的UI架構就分析完成了,看出什麼門道來沒有?是的,我們以開機動畫為切入點,從Linux核心空間的FB驅動,一直分析到使用者空間中HAL層模組Gralloc、C/C++ Runtime Framework層的SurfaceFlinger、Java Runtime Framework層的WindowMangerService、Window、Widget,以及資源管理框架,從下到上,披荊斬棘。

        6. Dalvik虛擬機器 -- 橫線

        Android系統的應用程式及部分應用程式框架是使用Java語言開發的,它們執行在Dalvik虛擬機器之上,還有另外一部分應用唾棄框架在使用C/C++語言開發的。使用Java語言開發的應用程式框架老羅稱之為Java Runtime Framework,而使用C/C++語言開發的應用程式框架老羅稱之為C/C++ Runtime Framework,它們被Dalvik虛擬機器一分為二。通過前面的學習,其實我們都已經瞭解Android系統的Java Runtime Framework和C/C++ Runtime Framework,因此,我們最後將注意力集中在Dalvik虛擬機器上:

        Dalvik虛擬機器簡要介紹和學習計劃

        Dalvik虛擬機器的啟動過程分析

        Dalvik虛擬機器的執行過程分析

        Dalvik虛擬機器JNI方法的註冊過程分析

        Dalvik虛擬機器程式和執行緒的建立過程分析

        學習完成“三橫三縱”這六條主線之後,我們就可以自豪地說,從上到下地把Android系統打通,並且將它的骨架和脈絡也理清了!

        對於“準備”、“專用驅動”、“HAL”、“應用程式元件”這四條主線,老羅極力推薦大家看《Android系統原始碼情況分析》一書,內容比部落格文章要系統、詳細很多,不說其它的,就單單是講Binder程式間通訊機制的那一章,就物超所值。在《Android系統原始碼情景分析》一書中,老羅最引以為豪的就是講Binder程式間通訊機制的第5章,網上或者其它書上絕對是找不到這麼詳盡的分析資料。

        五. 將來要做的事情

        接下來要做的主要是三件事情:

        1. 繼續研究Android系統

        本來以為前段時間的Google I/O會發布Android 4.3或者5.0,然後老羅就以最新發布的版本為藍本來進行研究。既然沒有釋出新版本,那麼就只有以現在的最新發布版本4.2為藍本進行研究了。如前所述,4.2與2.3相比,最大的不同之處是預設增加了GPU支援,因此,老羅在接下來的一段時間裡,將著重研究4.2的GPU支援。

        2. 停止部落格更新

        這兩年投入在部落格上的精力太多了,部落格上的文章基本上熬夜熬出來的。大多數時候,一個話題要花一個星期左右的時間來看程式碼,然後再花四個星期左右的時間將文章寫出來。本來是這樣計劃的,依靠《Android系統原始碼情景分析》一書的銷量,可以在經濟上得到一定的回報,然後可以繼續在部落格上投入,直至把4.x版本的GPU支援寫完,最後再整理出一本關於Android系統UI架構的書。但是最近詢問了一下書的銷量,差強人意,達不到預期目標。由於沒有形成良性迴圈,因此沒有辦法,只好停止部落格更新。老羅需要把精力投入在其它事情上,希望大家諒解!

        3. 仍然會持續地進行一些小分享

        主要是一些隨筆分享,這些分享主要會發布在微博或者QQ群上面,那裡也方便一些和大家進行討論。此外,老羅也樂意和大家進行一些線下分享,主要針對企業或者單位組織的沙龍、活動和會議等,同時也可以單獨地針對企業內部進行分享。不過前提當然是舉辦方對《老羅的Android之旅》專欄或者《Android系統原始碼情景分析》一書的內容感興趣,並且邀請老羅去參加。

        如果需要邀請老羅去參加分享,可以通過微博或者郵箱和老羅聯絡,非常感謝大家兩年以來的支援!

        郵箱:shyluo@gmail.com

        微博:http://weibo.com/shengyangluo

相關文章