移動開發的消亡史:出路在哪?
熱文導讀| 點選標題閱讀
作者 | 徐川編輯 | 小智寫在前面今天,我想給大家講一段故事,這個故事裡包含有黑科技、天才少年,有意氣風發的豪情和壯志未酬的遺憾。更重要的是,這是一段真實的故事,是我人生中的一段重要經歷。
對於網際網路人來說,這個冬天格外寒冷。
“辛苦一年半,現在要被聯合創始人給踢出局了,技術創業真是悲哀。”一個沉寂已久的微信群裡,突然冒出了這樣一句話。
我看了一眼發訊息的人,備註是“勇哥 創業”,我心裡一緊。
群友被這個訊息炸出來,有的看熱鬧,有的義憤填膺,紛紛要求曝光無良公司。我卻不由得回想起當初與勇哥結識的故事。
勇哥大名叫張勇,我與他相識是在 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
蘋果“熱修復門”事件回顧和分析
Apple starts rejecting apps with “hot code push” features
https://news.ycombinator.com/item?id=13817557
作者介紹
徐川,InfoQ 中文站主編,專注移動開發、大前端領域,GMTC 全球大前端會議總編。
想進阿里嗎快加入我們的知識星球吧,如下?
如有收穫,歡迎「分享 」
「點贊」「評論 」
如你有好的文章想大家狀語從句:歡迎分享投稿,直接向我投遞文章連結即可
最後,國慶福利來了,我們的知識星球已達到1000人了,之前說過到達1000人時將大大幅漲價到169元,為了反饋大家對我們的關注和厚愛,特此維持現價99元最後一天,今天后(今晚00:00)後將漲到169元,歡迎大家加入我們的知識星球,更多星球資訊參見:
微信掃描或者點選上方二維碼領取的Android \ Python的\ AI \的Java等高階進階資源
更多學習資料點選下面的“閱讀原文 ”獲取
相關文章
- 移動端點選事件延遲的誕生消亡史事件
- 革命性移動端開發框架-Flutter時間簡史框架Flutter
- 我們習慣的前端開發正在消亡前端
- 【Flutter實戰】移動技術發展史Flutter
- AI Agent應用出路到底在哪?AI
- Android 開發的出路和精進之路Android
- 【移動端開發】移動端開發基礎問題
- 無線城市出路在哪?從深度解讀
- YonBuilder移動開發-移動原生外掛開發環境配置教程UI移動開發開發環境
- 關於移動網際網路測試的發展史的科普
- 移動端開發技巧
- 移動開發即服務,騰訊雲移動開發平臺打造開發新模式移動開發模式
- 移動支付市場發展史,聚合支付正當紅
- 我的移動開發春季歷程移動開發
- 程式設計師年度總結:2019年,你的出路在哪?程式設計師
- 學界 | 讀計算機博士的未來出路在哪裡?計算機
- 移動web開發總結Web
- 移動端開發小結
- 移動web——移動web開發簡介,WebStorgae簡介Web
- 急,想知道怎樣能拿高薪,轉行的出路在哪裡?高薪
- 無伺服器計算的機器學習,出路在哪裡?伺服器機器學習
- Excel?責任混亂?資金不足?倉庫管理的出路在哪Excel
- 產地銷茶葉的出路在哪裡?泉州志強茶莊
- 李開復:移動網際網路最大的賺錢機會在哪裡
- 移動端App開發 - 01 - 開篇APP
- 移動端快速開發的祕密武器
- 移動前端開發和Web前端開發的不同點介紹前端Web
- 移動開發技術有哪些?移動開發
- 移動web開發小貼示Web
- H5移動端開發H5
- 前端開發移動端除錯前端除錯
- web移動開發總結(六)Web移動開發
- 移動開發者如何賺錢移動開發
- 使用Termux打造你的移動開發平臺UX移動開發
- 移動端跨平臺開發的深度解析
- 2019年移動開發,我的求變之路移動開發
- 資深架構師講述:3—5年程式設計師的發展和出路在哪裡?架構程式設計師
- 移動APP開發框架盤點2:Web移動前端框架大全APP框架Web前端