這篇文章將為大家詳細(xì)講解有關(guān)小程序如何實(shí)現(xiàn)多進(jìn)程,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
羅平網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,羅平網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為羅平上1000家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)營(yíng)銷網(wǎng)站建設(shè)要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的羅平做網(wǎng)站的公司定做!
小程序這個(gè)名詞相信大家已經(jīng)不陌生了,繼微信之后,阿里巴巴、百度、頭條等大廠相繼實(shí)現(xiàn)了自己的小程序。小程序是一種全新的開放能力,開發(fā)者能夠快速開發(fā)出小程序并集成進(jìn)宿主,實(shí)現(xiàn)推廣等目的。
從使用角度看,小程序有輕量,易用等特點(diǎn);
從技術(shù)角度,以Android端為例,小程序有部分組件原生化、UI和邏輯線程隔離、小程序之間進(jìn)程隔離等等。
下面主要從小程序進(jìn)程隔離角度出發(fā),分析BAT的小程序多進(jìn)程的實(shí)現(xiàn)方案,并自己實(shí)現(xiàn)一個(gè)小程序的多進(jìn)程。
多進(jìn)程,顧名思義,即每一個(gè)小程序都是一個(gè)單獨(dú)的進(jìn)程。這個(gè)效果只在Android端獨(dú)有。那為什么我們希望小程序之間實(shí)現(xiàn)進(jìn)程隔離呢?原因大致有三點(diǎn):
由于是單獨(dú)進(jìn)程,無論小程序內(nèi)部因?yàn)楹畏N原因的崩潰,對(duì)主進(jìn)程都沒有影響,增強(qiáng)用戶體驗(yàn)。
由于每個(gè)進(jìn)程都有一片單獨(dú)的內(nèi)存區(qū)域,小程序不會(huì)占用主進(jìn)程的內(nèi)存,降低了內(nèi)存溢出的風(fēng)險(xiǎn)。
由于不同進(jìn)程間的內(nèi)存是隔離的,當(dāng)同時(shí)開啟多個(gè)小程序時(shí),內(nèi)存變量、參數(shù)等數(shù)據(jù)互不影響,也可達(dá)到一個(gè)解耦的目的。
既然是分析多進(jìn)程這種用戶感知不強(qiáng)烈的技術(shù)點(diǎn),我們需要通過一些工具或命令。
進(jìn)程分析
首先,我們把微信完全殺死又重新開啟,然后通過 adb shell ps | grep com.tencent.mm 命令,可以查看正在運(yùn)行的進(jìn)程名稱和數(shù)量,其中 grep com.tencent.mm 是過濾微信相關(guān)的進(jìn)程,因?yàn)槲⑿诺陌莄om.tencent.mm。此時(shí)進(jìn)程運(yùn)行狀況如下圖:
此時(shí)我們只能看出微信從完全關(guān)閉到啟動(dòng),開啟了6個(gè)進(jìn)程,但是還看不出這些是否與小程序相關(guān)。于是,我們打開一個(gè)小程序,再次執(zhí)行 adb shell ps | grep com.tencent.mm 命令,此時(shí)進(jìn)程運(yùn)行狀況如下圖:
對(duì)比之后,就可以做一些分析了。其中,com.tencent.mm是主進(jìn)程,com.tencent.mm:push應(yīng)該是與推送相關(guān)的進(jìn)程,com.tencent.mm.tools和com.tencent.mm:toolsmp應(yīng)該都是一個(gè)類似于Helper的相關(guān)進(jìn)程,因此我認(rèn)為最有可能的是com.tencent.mm:appbrand2,因?yàn)檫@個(gè)命名比較特殊,前面分別有appbrand0和appbrand1兩個(gè)進(jìn)程出現(xiàn)過。那么為什么新開的第一個(gè)小程序,反而多出來的進(jìn)程時(shí)appbrand2呢?我個(gè)人猜測(cè)這與微信小程序的預(yù)加載有關(guān)系,很有可能是,這個(gè)進(jìn)程是空的,只是先fork出來,并沒有做過多的事情,真正承載我們開啟的那個(gè)小程序的進(jìn)程,很有可能不是這個(gè)appbrand2。那么如何驗(yàn)證呢?進(jìn)入第二步,Activity分析。
首先打開一個(gè)小程序,然后通過 adb shell dumpsys activity activities 命令,可以看到所有棧內(nèi)的Activity信息,滑到頂部,查看正在與用戶交互的Activity信息,如下圖:
關(guān)鍵的信息我已經(jīng)用紅色圈了出來,processName=com.tencent.mm:appbrand0,realActivity=com.tencent.mm/.plugin.appbrand.ui.AppBrandUI,這大致已經(jīng)驗(yàn)證了我們剛才的猜想,即:
com.tencent.mm:appbrand系列,是與小程序相關(guān)的進(jìn)程。
微信預(yù)加載2個(gè)空進(jìn)程作為預(yù)加載,避免用時(shí)再fork進(jìn)程,耗時(shí)過長(zhǎng)影響用戶體驗(yàn)。
為了進(jìn)一步驗(yàn)證猜想是否正確,我下載了微信最新版本的apk,進(jìn)行了逆向操作,也就是第三步,分析apk。
反編譯的方法大家自行搜索,這里就不贅述了。我們打開反編譯后的AndroidManifest.xml文件,搜索剛才的的Activity名稱,結(jié)果如下:
得到的信息與剛才一致。然而,我們又發(fā)現(xiàn)了另一個(gè)問題,那就是AppBrandUI還有另外4個(gè)兄弟,即AppBrandUI1,AppBrandUI2,AppBrandUI3,AppBrandUI4,而這四個(gè)Activity的名稱與綁定的進(jìn)程,又能夠與一開始的appbrand對(duì)應(yīng)起來,經(jīng)過試驗(yàn),我發(fā)現(xiàn)微信最多只可以啟動(dòng)5個(gè)小程序,而這些小程序的載體就是這5個(gè)Activity,不斷輪詢,超過5個(gè)時(shí),將第一個(gè)結(jié)束掉。這樣,我們就基本可以確定,微信是通過apk內(nèi)置的5個(gè)Activity,來實(shí)現(xiàn)小程序的多開與進(jìn)程隔離的。
因此,理論上這5個(gè)Activity應(yīng)該是除了進(jìn)程不同,內(nèi)部邏輯應(yīng)該都是相同的,于是我們繼續(xù)驗(yàn)證,反編譯代碼后找到AppBrandUI1這個(gè)Activity,結(jié)果如下圖:
AppBrandUI2,AppBrandUI3,AppBrandUI4與此完全一樣,都是繼承了AppBrandUI,做了極少的事,由于微信代碼混淆過,我們無法看出那幾行代碼具體做了什么,但是基本可以理解為完全復(fù)用。至于為什么分開寫,而不是復(fù)用同一個(gè),我猜測(cè)原因可能有二:
由于語法限制,為Activity開辟進(jìn)程需要在AndroidManifest.xml中預(yù)先配置
2. 微信不僅將小程序進(jìn)程隔離,并且還進(jìn)行了棧隔離,當(dāng)我們同時(shí)開啟多個(gè)小程序時(shí),長(zhǎng)按Home鍵,可以發(fā)現(xiàn)存在多個(gè)小程序任務(wù)卡片,這種效果同樣需要在AndroidManifext.xml中配置taskAffinity屬性,這在上圖中也有體現(xiàn)。
另外,我還注意到,微信在AndroidManifest.xml中配置了這樣的Receiver:
這種Receiver共有5個(gè),每個(gè)小程序進(jìn)程有一個(gè),其它4個(gè)只是繼承了這個(gè)AppBrandTaskPreloadReceiver,由于混淆的原因,無法看出具體做了什么事,但是通過名字判斷,是實(shí)現(xiàn)小程序進(jìn)程預(yù)加載的,空閑時(shí)開啟這個(gè)廣播,至少可以提前開啟進(jìn)程,避免用時(shí)再加載耗時(shí)過長(zhǎng)影響用戶體驗(yàn)。
同樣的,我分析了百度和支付寶的apk,通過命令和反編譯等方法,發(fā)現(xiàn)他們的方案幾乎一樣,只是預(yù)加載的數(shù)量等一些小細(xì)節(jié)不同,感興趣的同學(xué)可以自己逆向之后做對(duì)比。
分析總結(jié)
1. 微信對(duì)每個(gè)小程序都做了進(jìn)程隔離和棧隔離,互不影響。
2. 實(shí)現(xiàn)這一功能的載體Activity是預(yù)先配置在AndroidManifest.xml中的。
3. 通過某種方法,微信將小程序的最大運(yùn)行數(shù)量控制在5個(gè)。
4. 微信對(duì)多進(jìn)程做了一些優(yōu)化,已知的是預(yù)加載2個(gè)空進(jìn)程。
5. BAT等大廠的小程序多進(jìn)程方案大同小異。
一. Application初始化
Android的app在開啟多進(jìn)程時(shí),每開啟一個(gè)進(jìn)程,Application都會(huì)重新創(chuàng)建,也就是onCreate函數(shù)會(huì)被調(diào)用,如果沒有做進(jìn)程判斷,所有東西會(huì)初始化多次,造成卡頓或意料之外的bug。
二. 分配與管控
由于進(jìn)程之間的內(nèi)存無法共享,小程序的生命周期需要在某一個(gè)進(jìn)程中維護(hù),不然無法做到動(dòng)態(tài)分配進(jìn)程和棧,而這個(gè)進(jìn)程選擇主進(jìn)程最為合適。因此需要?jiǎng)?chuàng)建一個(gè)管理器,這個(gè)管理器負(fù)責(zé)以下幾件事:
1. 接收外界開啟、關(guān)閉等對(duì)小程序的操作
2. 合理的為接收到的請(qǐng)求分配空閑的進(jìn)程
3. 接收遠(yuǎn)程小程序的生命周期回調(diào)并通過某個(gè)uuid進(jìn)行維護(hù)
4. 在空閑時(shí)預(yù)加載進(jìn)程
5. 根據(jù)設(shè)置的可開啟的最大小程序數(shù)量,對(duì)進(jìn)程進(jìn)行新建、銷毀等操作
6. 所有這些管理和維護(hù)的操作,對(duì)小程序接入者都應(yīng)是透明的,無需關(guān)心具體實(shí)現(xiàn)流程,僅在需要時(shí)開啟小程序即可。
三. 進(jìn)程生命周期問題
Android系統(tǒng)對(duì)于內(nèi)存有一套自己的管控機(jī)制,當(dāng)內(nèi)存較為緊張時(shí)會(huì)在不做任何通知的情況下kill掉活躍度較低的進(jìn)程,至于進(jìn)程活躍程度,就與Android的進(jìn)程?;钣嘘P(guān)了,可通過設(shè)置前臺(tái)進(jìn)程、喚醒等方式去盡量?;睢5菬o論應(yīng)用端再怎么做,都無法逾越操作系統(tǒng)的權(quán)限,系統(tǒng)在某些情況下依然會(huì)把進(jìn)程殺死來保證整個(gè)系統(tǒng)的正常運(yùn)行。因此,開發(fā)時(shí)需要做容錯(cuò)處理,不能僅以Activity的onDestroy回調(diào)為準(zhǔn),因?yàn)橐坏┏霈F(xiàn)系統(tǒng)級(jí)的回收,很可能導(dǎo)致整個(gè)分配管理器的錯(cuò)亂。
四. 通訊
通信又分為兩個(gè)方面,第一,小程序進(jìn)程與app主進(jìn)程是隔離的,需要進(jìn)程間的IPC通信;第二,小程序的本質(zhì)是一個(gè)web容器,這就少不了js與原生的通信,需要jsbridge。下面分別說一下這兩個(gè)方面。進(jìn)程通信:
IPC的實(shí)現(xiàn)已經(jīng)不是什么問題,這里僅說幾個(gè)需要注意的點(diǎn):
1. 通信一定是雙向的,無論哪個(gè)進(jìn)程,最好綁定同一個(gè)服務(wù),方便數(shù)據(jù)的維護(hù)。
2. 由于通信較為頻繁,建議使用基于Binder的通信機(jī)制,可以提高運(yùn)行效率。
js與原生通信:
js與原生通信一定是通過jsbridge,最好做法是將原生方法的實(shí)現(xiàn)寫在主進(jìn)程,分布在不同進(jìn)程的小程序向主進(jìn)程請(qǐng)求某個(gè)bridge的實(shí)現(xiàn)結(jié)果,主進(jìn)程根據(jù)相應(yīng)的參數(shù)去執(zhí)行并返回結(jié)果,類似于一套CS的架構(gòu)。即小程序客戶端無需關(guān)心具體操作,只關(guān)心結(jié)果并響應(yīng)給web端。
關(guān)于小程序如何實(shí)現(xiàn)多進(jìn)程就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
文章名稱:小程序如何實(shí)現(xiàn)多進(jìn)程
網(wǎng)頁地址:http://aaarwkj.com/article30/phodpo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、企業(yè)建站、ChatGPT、外貿(mào)網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化、移動(dòng)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)