移動開發的羅曼蒂克消亡史

寫在前面

今天,我想給大家講一段故事,這個故事裏包含有黑科技、天才少年,有意氣風發的豪情和壯志未酬的遺憾。更重要的是,這是一段真實的故事,是我人生中的一段重要經歷。

對於互聯網人來說,這個冬天格外寒冷。

“辛苦一年半,現在要被聯合創始人給踢出局了,技術創業真是悲哀。”一個沉寂已久的微信羣裏,突然冒出了這樣一句話。

我看了一眼發消息的人,備註是“勇哥 創業”,我心裏一緊。

羣友被這個消息炸出來,有的看熱鬧,有的義憤填膺,紛紛要求曝光無良公司。我卻不由得回想起當初與勇哥結識的故事。

勇哥大名叫張勇,我與他相識是在2015年秋季,當時我正在一個程序員論壇上閒逛,突然一個帖子映入我的眼簾:“搞了個安卓上免安裝運行的,準備開源一下”。這個帖子一下子就引起了我的興趣。

移動開發正是我當時的關注領域,我對智能手機上一切前沿的、好玩的技術都充滿好奇。帖子裏說,他的這個技術可以通過主App啓動任意第三方App,我以前從未聽說過這樣的技術。

很快,通過朋友介紹,我和帖子的作者張勇搭上了線,他當時是安卓版360手機助手的技術負責人,9月份,我前往酒仙橋360總部,與他見了面。

張勇敦厚面相中透着機靈,和大部分程序員不一樣,他十分健談,說起自己開發的DroidPlugin眼裏帶着光。和他聊了兩個小時,我確信,這是一項安卓開發黑科技。

安卓黑科技

中國的技術都是業務驅動的,先有需求,然後研究怎麼能做到,DroidPlugin誕生的背景也是如此。

14年左右,中國和國外的App理念走上了截然不同的兩條道路。在國外,一個App最多做兩三件事,但在中國,一個App恨不得裝下所有功能,這就是所謂的超級App。

超級App有很多好處,但是,谷歌在設計安卓的時候,沒有考慮到存在超級App的情況,在安卓早期版本里,一個App裏只允許存在65536個方法,一旦超過就會報錯。65536已經很大了,就和千年蟲問題一樣,開發安卓的工程師們根本沒想到有App會需要那麼多的方法。

這個問題在國外被Facebook發現了,Facebook的App很大,可能是國外僅有的幾個可以稱作超級App的應用了,它給出了一個暫時繞過的解決辦法。

國內開發者不滿足這種暫時繞過的方法,早在2012年,大衆點評的工程師圖毅敏在研究Android源碼的過程中就發現,通過對AndroidDynamicLoader方法的應用,可以做到動態加載資源甚至代碼。2014年底,當時在百度的安卓工程師任玉剛開源了Dynamic-load-apk,將這種方法更進一步。

到張勇這裏,他把動態代理發展到了極致,讓Android系統的四大組件都可以動態加載,這樣,安裝App的時候只用裝一個宿主App或者叫殼App,然後在宿主App裏遠程下載代表各個功能模塊的App就行了。這種技術流派,後來被稱爲安卓插件化技術。

想象一下,你的手機只用安裝一個App,如果想用其它App,點擊下載之後就可以運行,省去了麻煩的安裝過程,甚至你還可以用不同的賬號同時打開一個App,這就是插件化的神奇之處。

安卓插件化的一個變種是組件化技術,它並不用分成不同的App,而是平時各個模塊分開開發,發佈的時候一起打包,這種技術的集大成者就是手機淘寶研發的Atlas組件化框架,2014年初伯奎對外首次分享,2017年3月正式開源。

超級App還會帶來一個問題,就是App的更新,當App由數十個團隊,數百上千人開發,版本控制和更新變成了一個很麻煩的事情,特別是線上版本發現bug時需要及時更新版本處理,而國內安卓渠道衆多,依賴各個平臺更新是不現實的,只有自己處理更新,爲了降低更新給用戶帶來的影響,國內又發明了熱更新技術。

早期的熱更新技術借鑑了安卓極客最愛的工具Xposed,2015年7月左右,淘寶的白衣開源了安卓切面編程框架Dexposed,它在Xposed的基礎上進行改造,使其不需要root就可以任意改變應用的功能。但是,這個技術只支持Dalvik運行時,對於新的ART運行時無能爲力。隨後不久,支付寶安卓團隊推出了AndFix,能很好的支持ART,很快成爲阿里系的標準熱更新工具。

騰訊這邊,QQ空間在2015年分享了它的熱補丁技術,它是基於谷歌爲了解決方法數溢出而推出的MultiDex方案,第二年微信推出了更好的熱更新框架Tinker,也被廣大的開發者所喜愛。

2016年,美團的人告訴我,他們在研究了Android Studio 2.0裏的Instant Run功能後,推出了Robust熱更新框架,成爲安卓熱更新的一個新的技術流派。

插件化、組件化、熱更新,從2015年開始,國內的移動開發技術爆發了井噴式的發展,這些是國內獨有的技術,在這一期間涌現出無數開發者,他們抱着極大的熱情研究技術並進行開源和分享,那是一個對移動開發者最好的時代。

在這一羣人中,我有兩個人印象比較深刻。

天才少年

2016年初,我開始籌辦GMTC全球移動技術大會,找張勇推薦講師,他給我介紹了羅迪。從勇哥的描述裏,顯然他對羅迪的技術極爲認同,然而讓我大吃一驚的是,羅迪當時才高二,還是個在校學生。

我一度懷疑他的技術水平,不過在通過郵件和微信交流後,我打消了這種懷疑。他當時已經開源了幾個Android插件化方面的工具,其中包括ART運行時的Hook工具Legend,這是當時最前沿的課題。在交流中我也瞭解到,他對插件化技術發展有深入的洞察,讓我十分佩服。

毫無疑問這是一個天才少年。據他自述,他從初二開始自學編程,初三開始學Java和安卓開發,業餘時間全部用來學習和研究Android源碼,這一點,就連職業的開發者也難以做到。他的天才並不是說具有學習和編程的天賦,而是可以靜下心來學習在一般人看起來枯燥的技術。

不過,雖然我認同他的技術,但是在權衡之後我還是放棄了讓他當講師的想法,因爲不想拔苗助長。但我邀請他來參加GMTC大會,以及一個安卓的閉門會議,並在閉門會議上做一個分享。

6月24號,GMTC如期舉行,我也見到了羅迪,他在微信上很活躍,但在現實中看上去比較木訥,講一句話需要思考一段時間,不太擅長與人打交道。

他說,插件化今後的方向是沙盒和雙開,後者又被稱爲“分身”,曾有一段時間,各種手機遊戲小號、微信分身非常火,就是用的這種技術。

值得一提的是,當年那次閉門會議,幾乎囊括了當時在安卓插件化方面研究最前沿的一批人,會議結束後,我請他們吃飯,拍照留念,現在一看,全是回憶。

圖片
(GMTC2016 安卓插件化閉門會議合影,後排右二是羅迪)

當時的羅迪已經被市場所發現了,我發佈了採訪他的文章後,有人專門給我寫郵件想讓我把羅迪介紹給他,張勇還告訴我有老闆專門到北京就是爲了看他。

再後來我沒有他的消息了,不過,他給我帶來了一點體會:當一個行業井噴時,會有這樣超出常理的天才涌現。

Bang和他的JSPatch

上面介紹的技術都是安卓平臺的,iOS和安卓平臺的技術差異很大,像插件化這樣的技術不太可能實現。在那幾年裏,iOS討論最多的是組件化。

不過,iOS和安卓有一個共同的需求,那就是熱更新,和安卓分發渠道太多不同,iOS需要熱更新,是因爲蘋果審覈太慢,以及審覈容易發生意外,雖然蘋果有快速審覈通道,但那遠遠不夠。我們需要能繞過蘋果審覈的更新辦法。Bang的JSPatch應運而生。

Bang曾經在百度工作過,後來去了微信讀書,JSPatch就是他在這段時間開發出來,並以個人名義開源的。

Bang是潮汕人,2016年我邀請他參加了第一屆GMTC大會,在短時間的接觸中,感覺似乎比較靦腆,但在網絡上,他有一個博客,我很喜歡看他的博文,不僅言之有物,而且能切中要害。

Bang因爲JSPatch而名聲鵲起,GMTC的時候他的演講爆滿,有人專門過去看他。

JSPatch並不是第一個iOS熱更新工具,在之前還有基於Lua的WaxPatch,後來由淘寶的君展維護,但WaxPatch需要帶一個Lua運行時會增大體積,而JSPatch則頗爲小巧,藉助iOS平臺內嵌的JS引擎,代碼行數長期保持在2000行以下。從2016年起,我瞭解到的國內大多數頭部應用,幾乎全部使用了JSPatch,包括互相之間存在競爭的BAT巨頭們,在注重門戶之見的國內,這實在是個了不起的成就。

然而,正因爲JSPatch的流行,當蘋果決定收緊審覈政策時,JSPatch首當其衝,結果讓整個中文互聯網幾乎都受到了影響,這個下面再談。

百花齊放的時代

2016年,國內的移動開發技術發展到了最鼎盛的時期。插件化/熱更新成爲顯學,成爲高級工程師的必修課。

張勇在樂視最風光的時候去了樂視體育,後來又被人鼓動,以技術入股的形式去做PC安卓模擬器的創業。

360安全衛士的張炅軒等,開發了一個更完美的插件化技術RePlugin,並在2017年的GMTC上開源。

微信發佈了Tinker,美團發佈了Robust。

聚划算的樸誠發佈了LuaView,另一個基於Lua的iOS熱更新工具。

剛剛收到蘋果投資的滴滴宣佈合併Uber中國,它招募了當時iOS領域的大牛Sunny孫源和安卓的任玉剛,開始在移動技術上大展拳腳。過不久,Sunny就推出iOS動態化方案DynamicCocoa,它比JSPatch更加激進,已經有安卓插件化的幾分模樣;曾鼓搗出Dynamic-load-apk的任玉剛則推出安卓插件化方案VirtualAPK,與RePlugin同臺競技。

QQ還推出了一個號稱史上最瘋狂的iOS動態化方案OCS,它們開發了一個自己的中間語言OCScript,還開發了一個自己的虛擬機OCSVM去執行它……稍微懂點編程的就知道這是一個多麼瘋狂的方案。

那的確是一個百花齊放的時代。而身處這個時代甚至參與其中,幾乎每天我都活在激動當中。

很多人不知道的是,InfoQ的願景是推動軟件技術發展,這是一個頗顯狂妄的說法,技術推動社會發展,而我們要推動技術發展。我將它當作了我的職業信條。在那段時間裏,我能感覺到所處領域每天都在往前發展,能感覺到我所作的事情,無論是報道和微信社羣,還是線下大會和沙龍,就像拓荒一樣,都在一點點的推動這個領域的外延更加擴大。沒有比這更好的工作了。

當時我發現一個問題,就是這些黑科技只在國內發展,沒有人把它介紹到國外去,國內外之間缺乏交流。於是我給InfoQ英文站的社區編輯Sergio De Simone寫了一封郵件,看看有沒有可能對國內的技術做一些報道。Sergio是一名軟件工程師,業餘時間幫InfoQ英文站寫了許多技術報道,其中大部分是移動領域的。

然而Sergio的回覆讓我比較沮喪,他認爲這些技術違反蘋果和谷歌的規則,不太可能在國外應用,因此報道的興趣不大。曾經動過想把張勇推薦到國外QCon的心思也熄滅了。

2016年6月的閉門會議上,我號召大家多多在國外網站和社區上推廣插件化技術,可惜沒人聽進去,在我瞭解的範圍內,唯一做過這方面的努力的是LBE的馮森林,他在參加Google IO的時候向國外工程師演示插件化的神奇,據說當時老外驚呆了。後來谷歌推出了自己的免安裝應用Instant Apps,不知道是否有受到啓發。

現在回想起來,我當時可以做得更多的,即使未必有用,但總得試一試。

然而還沒有等我再次鼓起勇氣,蘋果的打擊到來了。

蘋果的一封信

2017年3月,衆多iOS開發者收到警告郵件,聲稱其App違規使用動態方法,責令限時整改。

這封郵件引起了開發者的恐慌,連React Native都遭受池魚之殃,經過一番尋找之後,發現問題集中出現在兩個熱更新工具Rollout和JSPatch上,其中Rollout國外用的較多,JSPatch則主要是國內使用。

在當時的分析文章裏,該事件的影響一節裏我寫道:

在國外,本次警告事情其實受影響並沒有那麼大,國外iOS平臺熱修復或熱更新並不流行,Rollout的聲明裏,本次只有數百個App、數百萬最終用戶受到影響。

但在國內,這一數字要遠遠超出。去年以來,凡是公開分享過iOS應用架構的,都將熱修復作爲其基礎設施之一,可以說大部分頭部應用都有使用JSPatch或類似方案。本次受影響的國內App數以千計,覆蓋的人羣則包括幾乎所有中國iOS用戶。

更長遠的影響是,熱修復對一個團隊的開發流程和節奏緊密相關,很多團隊都必須修改相應的開發流程來適應變化。

這一判斷並沒有誇張,在蘋果警告之後,iOS動態化的工具都轉入地下發展,關於這方面的研究和分享也急劇減少,甚至連整個iOS技術的分享也變少了。在另一篇文章裏,我寫道:蘋果的一封郵件像《三體》的智子一樣鎖死了國內技術。從那以後,“iOS開發沒人要了”成爲一個梗,流行起來。

在安卓平臺,雖然谷歌沒有能力像蘋果一樣干涉國內的開發,但插件化技術從另一方面遭遇了困境。

這一困境就是安卓新版本以及國內各種魔改ROM對於底層的改動。安卓插件化技術依賴部分底層方法以及私有API,而這些在新版本里是很有可能改動的,一旦修改了,插件化就會失效甚至出錯。國內各大手機廠商的系統也喜歡對底層進行修改,它們的修改甚至都不會公開告知,因此兼容問題是插件化技術遇到的最大挑戰。

2018年發佈的Android 9.0,甚至要求開發者不得使用私有API,少了這些API,安卓開發被重新關回籠子裏,還能玩的黑科技大大減少,無意之中竟然取得了和蘋果警告類似的效果。

反思

在蘋果警告之後,我瘋狂的閱讀網上的報道,希望能看到轉機,然而越是讀下來,我的心裏越是冰涼。

在Hacker News對於事件報道的討論串裏,大部分人對於蘋果的行爲持贊同態度,原因是隱私和安全。

插件化和熱更新對隱私和安全的威脅在於,用戶無法控制或得知應用被偷偷的嵌入惡意代碼,部分插件化方案要求提前獲取所有插件App所需要的權限,這意味着開發者可以利用它來竊取用戶的隱私。

而隱私和安全在國外是一個禁區,不可越雷池一步,即使並沒有造成實際危害,只是有這方面的風險,相關的技術就不可能被允許。這個,其實Sergio早在一年前就告訴我了,然而我還抱着僥倖心理,並沒有重視他的回覆。

插件化和熱更新的問題就在於它們的能力太強大了,猶如過於鋒利的雙刃劍,從蘋果和谷歌的角度,必須要加以限制。

事實上,插件化已經被拿來做過壞事了,DroidPlugin就曾被黑產利用,在2017年爆發過Triada和TigerEyeing兩起病毒木馬事件。

至於熱更新實際上尚未造成危害,它只是被一家國外安全機構檢測到有風險,就遭到了蘋果的堅決取締。但在國內,它已有被濫用的苗頭,在蘋果警告事件中,有些沒有使用熱更新的App也收到了警告,後來才發現,有些第三方的SDK使用了JSPatch,而這些第三方開發商做些什麼,甚至連App開發者也不能控制!

所以,從這個角度來看,插件化和熱更新是需要防止濫用,而在之前,我只看到這些技術好的一面,對於它們的負面影響刻意忽視,違背了媒體中立的準則和監督的職能,現在回想起來,實在是不成熟。

從另一方面思考,我又難掩憤懣之情——蘋果和谷歌打擊插件化和熱修復,實在是太輕易了,並且,從始至終,它們從未與國內開發者有過溝通,從未考慮過國內的特殊情況。

蘋果取締熱修復,只需要通過一封郵件,它甚至都不需要修改審覈規則,而只需要暗中調整規則的解釋:iOS安全大牛蒸米在微博上說,警告中提到的動態方案,其實審覈上一直寫着不讓用,但是實際用了審覈也並不會被拒。而現在,它們只需要嚴格執行規則就行了。

而國內和國外,不僅在對待隱私上的態度不同,App的形態上也有差異,國內的超級App帶來的新需求,爲什麼不能讓蘋果爲國內市場單獨推出一些新功能和政策?

我深深的體會到,國內的這些移動開發技術,其實就是沙灘上的城堡,對於操作系統的路徑依賴,讓蘋果和谷歌哪怕做一些小小調整,也足以讓這些酷炫的黑科技遭到毀滅性打擊。

這段經歷讓我無比渴望國內出現自主的操作系統,讓我深刻理解了自主操作系統的重要性、底層技術和制定規則的重要性。然而我也知道,要做一款主流的操作系統,不僅僅是技術問題, 更重要的是歷史的機遇。

更實際些的考慮,要儘量避免類似的事件發生,我們需要儘量加強國內外的技術交流,避免雙方的技術差異過大。

2017年6月的第二屆GMTC的開場上,我提醒參會者:蘋果和谷歌一直在堅定的推動Web技術,在熱更新和插件化的道路選擇上,我們和國外走得越來越遠,這真的是一件好事情嗎?我們是否走了彎路?

然而,這已經是馬後炮,這些“黑科技”技術的衰落,已不可避免。

爲了忘卻的紀念

對我來說,這篇文章充斥着大量的回憶,格外難以動筆。

對於過去的事情,記憶難免有所美化,有些地方也可能記錯,讀者如果發現,還請海涵。

這段經歷對我的打擊甚大,在一段時間內,我甚至對移動技術失去了興趣,沙灘城堡的意象在腦海中揮之不去,看到新的技術總有一個聲音在耳邊說:沒有用的,只要蘋果爸爸稍微改改,這技術就得進歷史的垃圾堆……

在做移動開發內容和活動時交了一些朋友,也得罪了一些人,後來大部分也不再聯繫了……

插件化和熱更新技術是真的不可避免的衰落了,它們已經錯過了歷史機遇期,新的技術已經從另一個維度實施了降維打擊,沒錯,說的就是小程序。

據瞭解,有些大型App如淘寶等,已經開始用小程序來取代一些原生的功能模塊,這一職責正是插件化的範疇,而小程序的熱更新相比原生,更加簡單和自然。小程序還能成爲平臺吸引第三方入駐,這在插件化中只有在RePlugin那裏有些想法的雛形而已。

更大的改變則來自於行業風向的變化。頭條系“App工廠”取得的巨大成功,讓人們重新思考App矩陣的價值,人們不再往超級App里加功能,而是又開始開發新的App了,對這些App,插件化基本沒有用武之地。

很多移動開發者都轉行了,張勇最終還是和老闆協商解決了問題,投身到下一份工作裏。

Bang去了螞蟻金服,他還在堅持。在他2018年總結的博文裏,他寫道

JSPatch 8月開始遭受另一波審查升級,混淆的方案失效,蘋果確實針對JSPatch做了比較厲害的掃描手段並在不斷升級,今年跟審覈團隊溝通他們也是表示不喜歡JSPatch,還是那套審覈後不能修改的說辭,就算解決了安全問題也沒用,比較無奈,但熱修復需求還在,JSPatch平臺還是會繼續找解決方案。

蘋果仍然在趕盡殺絕。

插件化熱潮註定成爲技術發展的一段小插曲,也許再過幾年,不會有人記得了。那段激情飛揚的歲月,終將成爲The Wasted Times。


(電影《羅曼蒂克消亡史/The Wasted Times》劇照)

他一直拖到一九四九年五月初才坐上去香港的輪船,算得上真正的末班車。沒有人知道他在拖什麼或等待什麼,我想他自己也未必知道,不過是下意識的拖延。不久他就死在香港,死前再沒有值得記述的事件或說過的話,他基本沒再說話,這沒什麼可奇怪的,一切都不值一提,他終於走向自己的沉默。

我很喜歡這段話,覺得感同身受,做過什麼,發生什麼,到末尾一切都不值一提,然而我終究還是拿起筆,記下那些爲了忘卻的紀念。

延伸閱讀:

搞了個安卓上免安裝運行的,準備開源一下
https://www.v2ex.com/t/208960

Dexposed:Android 平臺免 Root 無侵入 AOP 框架
https://www.infoq.cn/article/2015/07/dexposed

專訪 DroidPlugin 作者張勇:安卓黑科技是怎樣煉成的
https://www.infoq.cn/article/2015/09/droidplugin-zhangyong-interview

專訪羅迪:高二 Android 大牛的成長之路
https://www.infoq.cn/article/2016/05/lody-interview

JSPatch 開源經驗分享
https://www.infoq.cn/article/jspatch-opensource

蘋果“熱修復門”事件回顧和分析
https://mp.weixin.qq.com/s?__biz=MzUxMzcxMzE5Ng==&mid=2247488291&idx=1&sn=a1ed75c7229ecb01fa3b9e82807b253b

Apple starts rejecting apps with “hot code push” features
https://news.ycombinator.com/item?id=13817557

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