1. 程式人生 > >專訪包建強:為什麼我說Android外掛化從入門到放棄?

專訪包建強:為什麼我說Android外掛化從入門到放棄?

2016年6月24-25日,GMTC全球移動技術大會將在北京舉行,本屆大會,我們邀請了《App研發錄》的作者包建強老師,前來分享《Android外掛化:從入門到放棄》的內容。這個有趣的標題引起了大家的興趣,我們就來採訪一下包建強老師,看看他為什麼會取這個標題,以及對移動應用架構和Android外掛化的理解。

InfoQ:請您介紹一下自己,目前主要關注哪些技術領域?

包建強:大家好。我是包建強。簡單介紹一下我自己,我工作12年了,有8年時間在惠普微軟這些軟體公司做一線開發,2012年進入網際網路,做了4年移動App。去年寫了本書,《App研發錄》,賣的還不錯,感謝大家捧場。我有一個技術部落格,堅持寫了6年,地址是:http://cnblogs.com/jax。

我是08年微軟MVP。這些年來我一直很珍惜這個榮譽,MVP講的是技術分享的精神,我雖然現在不怎麼寫技術部落格了,但遇到有想法的年輕人,還是會鼓勵他們把自己的經驗分享出來,至少要給若干年後的自己看。

我目前涉足的領域比較多,前段時間還在區塊鏈折騰,順手學了點Docker和Go語言,現在對VR很感興趣,在私下研究Google的SDK。

InfoQ:據說您要續寫《App研發錄》,能介紹一下接下來會寫什麼內容嗎?

包建強:當年寫《App研發錄》這本書時,留下些遺憾,比如說我只講了Android的框架設計,而沒有談到iOS,其實它們的思想是一致的,但是iOS並不能理解這一點,因為他們大都看不懂Android的程式碼。此外,iOS有自己的技術體系,比如cocospods,比如runtime,這都不是能和Android放在一本書寫清楚的,所以接下來我要寫一本給iOS開發人員看的《App研發錄》,也就是第二卷。

另一個遺憾就是當時我的Android外掛化技術還沒有想明白,所以書中就沒提到這塊技術,其實我是預留了它的位置的,這本書本來是有13章的,但是2015年突然冒出來很多Android外掛化的開源框架——我到現在還在懷疑這幫哥們是不是提前約好了這個時間點,然後很多新思想就把我搞暈了,就沒敢把寫好的那一章放到書中。現在證明這個決定是正確的,時隔半年,我對Android外掛化的認識已經發生了很大的變化,已經不是一章幾十頁就能把這個話題說明白的了,所以接下來《App研發錄》的第三卷講專門講Android外掛化技術。

如果還有第四卷,那就是MobileAPI和推送、IM技術,這都是很遠的事情了,我還不敢想。

InfoQ:移動應用架構在過去幾年取得了很大的發展,您對此有什麼看法?App架構還有發展的空間嗎?

包建強:無線的技術越來越成熟,已經從12年時的一片荒蕪,發展為現在的蔚然大觀。對於國人來說,我們比較關注的是這麼幾個點,熱修復,效能,開發效率,App體積,資料驅動產品。這些點目前都已經有了很好的解決方案。這個話題很大,我就不展開說了。

我04年剛出來工作的時候,IT行業正在從CS轉型為BS。CS就是客戶端-伺服器,04年之前大都是這樣的軟體,後來網際網路的技術成熟起來了,就開始把原先的系統都搬到網站上,這就是BS,全稱是Browser-Server。

後來BS做的多了,大家覺得BS太單薄,很多功能不支援,不如CS,於是就搞出個SmartClient的概念,也就是智慧客戶端,Outlook就是一個很好的例子,你可以離線讀和寫郵件,沒網路也可以,什麼時候有網路了,再發寫好的郵件發出去。

再後來Flash就火起來了,這個本來是網頁製作工具三劍客,卻陰差陽錯的成為了網頁富客戶端的鼻祖。於是便有了Flex,微軟這時候也來插一腳,搞出個Silverlight。與此同時,JavaScript也在發力,並逐漸取代前者,成為富客戶端的最後贏家,那時候有本書非常火,叫做《JavaScript設計模式》。

前面鋪墊了那麼多,就是想說明App也在走同樣的發展道路,先沉澱幾年,把網站的很多技術都搬過來,也就是目前的發展情況,差不多該有的也都有了,下一個階段就是從CS過渡到BS,Hybird技術就是上面說到的BS,但是有很多缺陷,尤其是WebBrowser效能很差,然後便出現了React Native,我們可以理解為富客戶端。再往前發展是什麼樣我不知道,但是這個發展週期是很清晰的。大家趕快盯緊了Facebook的開源專案,這哥們經常放大招兒,已儼然成為App技術界的風向標。

InfoQ:您曾經說過iOS領域的架構和Android與WP相比有些距離,您現在也這麼認為嗎?能否具體解釋一下?

包建強:Android和iOS領域的很多思想,都是來自於WP。我有幸在這3個平臺上都做過App。我是微軟出身,所以做C#有將近十年的經驗,而WP是基於C#和Silverlight的,所以我做WP是輕車熟路。比較可惜的是,WP中的技術和思想都是很好的,只是這個產品比不過Android和iOS,所以現在做移動的已經沒有多少人提它了,但是要知道,現在Android和iOS比較火的幾個技術和思想,都是從WP搬過來的。我舉幾個例子:比如說MVVM,這個思想最早就是微軟提出來的。微軟有一門技術叫Silverlight,用來取代Flash的,它是藉助於一種叫做XAML的XML語言,來繪製UI。Android和iOS現在最火的MVVM和MVP,都是來源於此。

在iOS開發裡,很多同學還在糾結Model該有哪些程式碼,ViewModel該有哪些程式碼,其實這個問題8年前我們就已經討論清楚了,結論是程式碼是死的,人是活的,開發團隊定一個標準,然後大家遵守執行,這就夠了。

再比如說iOS使用Xib還是手寫程式碼。大家之所以有這個爭論,其實是Xcode設計的原因。我用過Xcode、Eclipse、Android Studio還有微軟的Visual Studio,我認為Visual Studio是最好的IDE編輯器,沒有之一。畢竟這是微軟投入了巨大人力來做的一個產品。Xcode對Xib的支援很差,就是點一下啥都沒改,但是git立刻就顯示這個檔案被修改了,此外,Xib中冗餘的標籤太多,可讀性很差,這就導致了從iPhone火起來,程式設計師們就都選擇手寫UI,然後一傳十、十傳百,尤其是培訓學校也這麼教,就變成了業界標準。但是你看WP和Android,它們都是基於XML來繪製UI的,WP和Android的開發人員都已經習慣使用XML繪製UI,你讓他們手寫UI,他們會覺得很難。

由此而提到Xcode另一個反人類的設計,就是在Xib和後臺程式碼直接通過連線來生成事件方法,微軟的VisualStudio從02年就在ASP.NET支援這個功能,但十幾年下來結論是,培養了一群只會拖控制元件的程式設計師,他們不知道拖控制元件背後的原理,以至於對ASP.NET的生命週期不清楚,寫出很多效能很糟糕的程式。由此及彼,Xcode其實也是這個問題,那根線會很難維護,尤其是連線很多的時候,這時候,在程式裡為控制元件繫結事件反而是更好的選擇。

最後說到WP的墓碑機制。在App切到後臺時,會把當前狀態記下來,再切回到前臺時,之前的狀態會被從記錄中讀取,從而恢復到之前的狀態,這被稱為墓碑機制。這個機制是藉助於WP對資料繫結的支援,因為我把資料也就是Model實體與UI綁定了,所以我只要儲存Model實體物件,以後就可以還原到之前的狀態。

Android和iOS就缺少這樣的機制,主要是資料繫結做的不如WP靈活,導致了App因為記憶體不足而回收後臺應用佔用的記憶體時(iOS叫記憶體報警,Android叫記憶體回收),再把被回收內容的App切回到前臺時,這時候一些變數或者view為空就崩潰了。你們看過Android SDK的貪食者遊戲原始碼嗎?裡面是通過儲存貪食者的座標,從而使用者在旋轉螢幕銷燬UI後還能回到遊戲最後的狀態。頁面中有1-2個變數還好辦,如果有幾十個變數需要儲存狀態,就體現出WP墓碑機制的好處了。目前Android和ios的解決方案是重新走一遍當前頁面的初始化過程,讓使用者重新操作一遍剛才填寫的流程,儘量不讓App崩潰。

當然,上面說的都是我的個人見解,也沒有全對全錯之說,不要迷信權威,大膽質疑,多做實驗,然後再找我討論,誰對聽誰的。

InfoQ:您在GMTC中的議題叫做《Android外掛化:從入門到放棄》,請問這個標題代表什麼意思?

包建強:哈哈哈。我是覺得,如果這個演講主題是《Android外掛化:從入門到精通》的話,就體現不出真是想明白了這個領域。所以最近冒出來各種從入門到放棄、改行、住院、出家的技術書籍,我覺得那反而是說明作者是真的大徹大悟了,武俠小說裡面有寫,雖“飛花摘葉皆可傷人,草木竹石均可為劍”,就是這種境界。

不過要宣告的是,我對Android外掛化的認識,遠不如馮森林、張勇、羅迪這些人。

我有一個Android外掛化研究的群,三十多人,都是國內各個外掛化開源專案的作者、公司外掛化的實施者,以及傳經授道的部落格作者。我們都感受到Android外掛化技術基本已經成型了,隨著React Native的橫空出世,Android外掛化會慢慢退出歷史舞臺,也就是這一兩年的事情吧,所以要給後人留下點什麼,於是便有了這次技術分享。

我的分享講包括外掛化技術的歷史和各種八卦,各個技術流派,一些小例子,各個開源專案的思想,外掛化實施過程中遇到的問題,以及未來的發展方向。45分鐘,我儘量講的生動有趣一些。

InfoQ:您對Android外掛化的發展有什麼看法?

包建強:就像我前面說的,Android外掛化技術目前已經基本成熟了,各大公司也都有了自己的外掛化平臺,機制可能會有不同,因為外掛化有很多流派,每個流派的思想都不太一樣。

接下來說幾點外掛化的問題:

首先是這個新功能釋出和熱修復是兩碼事,但是我們把這二者都混在外掛化中了。這就有問題了。熱修復是很輕量級的東西,完全可以使用AndFix或Nuwa來解決,但是我們現在通常是使用釋出新的外掛來修復線上bug,一兩天一個外掛化版本,使用者會不停的下載升級外掛。

其實呢,外掛化是用來發布新功能的。一般來說,大版本是一個月一次,中途想上一個功能,這時候才是外掛化的最好使用場景。所以說,要把新功能釋出和熱修復拆開成兩套機制,而不要混為一談。

我再舉個例子,就是用外掛化來發布新功能。然後我就發現,在下一次釋出大版本之前,只有50%的使用者升級了外掛並使用的是新功能。這是因為Dalvik的機制導致的,一旦載入了這個外掛的原始版本,就會一直使用,即使你下載的新版本外掛,也只能在App退出程序後重啟才能生效。Android使用者一般不會殺App的程序,也就我們這些程式設計師或發燒友才知道要去什麼地方殺程序。為了解決這個尷尬的問題,我們曾經試圖把App做成多程序的,每個模組的外掛都是一個單獨的程序,外掛升級會自動殺之前外掛的程序,然後再啟動新的程序來執行新版本的外掛。這就是張勇的DroidPlugin的思想,在他的框架出來之前,國內的外掛化機制都是單程序的,都有我剛才說的這個問題。然後就有人給出一種解決方案讓App崩潰後重啟,雖然也能解決問題,但就會產生一種搞笑的場景,使用者正在酒店模組下單,這時因為機票模組的外掛升級而重啟,這是很讓人抓狂的事情。

其次,就是程式碼質量下降。開發人員不再像過去那樣『提心吊膽』的寫程式碼,生怕自己的一次疏忽而導致大面積崩潰而對公司生意產生影響。我剛才舉的那個例子,一兩天就要發一次外掛新版本來修復線上bug,就是程式碼質量下降的表現。

第三,就是四大元件都需要外掛化機制嗎?我是做那種旅遊行業App的,幾百個Activity,大都是列表或者詳情,然後有幾個詳情頁面可以下單或者使用者登入,它們更多的邏輯在於呼叫伺服器API獲取資料然後展示給使用者。所以類似於電商、旅遊、O2O領域的App,把Activity的外掛機制搞定就好了。

  • Service這個元件,大都用於線上音樂的App,因為後臺也要能播放音樂。此外,不管是哪款App,只要涉及到聊天,都需要Service外掛來幫忙修改App圖示上的未讀訊息數。
  • Broadcast和ContentProvider什麼時候使用?像手機助手、安全衛士這類的App會著重依賴於這些技術,所以你會看到DroidPlugin必須要實現這兩個元件的外掛化技術,因為作者是在360這家公司,而任玉剛的開源框架(目前途牛在使用),以及攜程的框架,他們只支援了Activity和Service就夠了,因為大多數電商App有這兩個就夠了。

第四,大家有沒有發現,外掛化技術只在中國會開花結果,國外的開發人員都在忙什麼?大概是老外覺得線上有崩潰或者嚴重錯誤,發個新版本讓使用者更新就是了,不是什麼大不了的事情。遇到類似於迅速釋出新功能的需求,Facebook會另闢蹊徑,發明了React Native,寫的是H5但執行的是Native原始碼,走這個變通的套路,當然也是悶頭研究了很久才對外公佈的,iOS差不多了,Android還有很大的效能問題還沒有解決,但我估計也就今年年底的事了。React Native的穩定,同時意味著外掛化的落幕。這就是Android外掛化的未來。

InfoQ:您精通Android、iOS、WP三個平臺的應用開發,請問您是如何學習的?對於初學者有什麼建議?

包建強:精通這個詞,我是真心不敢說的。所謂無知者無畏,我曾經以為自己很牛,尤其是《App研發錄》出版後聽到一片讚賞的時候,但隨著接觸到更多的開發人員,聽到更先進的思想,看到更牛逼的技術,我發現自己的很多技術落伍了。

比如我在寫書的這一年裡,因為這本書大部分在講Android,所以無形中就把iOS的技術拉下了,直到去年下半年看JSPatch的原始碼時,我才發現對runtime的理解還只是皮毛。再比如說iOS結合Cocoapods進行模組化拆分。

接下來,我介紹一些自己的學習心得。

  • 首先就是去寫程式碼。有一個做Android的哥們升級為架構師,需要了解iOS這門技術,來問我怎麼能迅速精通iOS,我就告訴他,別玩虛的,腳踏實地跟著iOS開發團隊做幾個需求,半年之後再來談這個話題。Android和iOS的很多現金思想可以相互借鑑,我建議做一門技術的同學,也適當學習另一門技術。
  • 咬著牙看開源專案。比如說JSPatch,怎麼看?我有個建議,你看JSPatch的版本提交歷史,從第一次提交看起,這時候的功能應該是最簡單的,也是最容易看懂的,然後看歷史每次提交都修改了哪些東西,你能搞清楚作者的思路是什麼。
  • Android外掛化雖然有被React Native取代的勢頭,但還是要搞清楚外掛化所涉及的各種思想和技術。我這一年來的心得是,這是提高自身內功的極好辦法。尤其是涉及到Android系統底層的各種Hook。
  • 寫技術部落格吧。每天看文章只能是看過,一個月後能沉澱下來的沒有多少,好記性不如爛筆頭。一開始你可以轉載或羅列精品文章的連結,慢慢的開始分享自己的心得,翻譯些技術文章,技術水平提高是一個循序漸進的過程。

From: http://www.infoq.com/cn/news/2016/04/baojianqiang-interview