Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
文主要參考week官方wiki。
Weex 是一個跨平臺解決方案,Web 平臺只是其一種運行環境,除此之外還可以在 Android 和 iOS 客戶端中運行,在Android的iOS平臺上運行時,jsbundle會被轉化成原生程序執行,原生平臺和 Web 平臺的執行環境存在一定差異,在功能和開發體驗上都有一定差異,尤其要注意web平臺執行環境中特有的BOM和DOM對象。
主要差異如下:
DOM(Document Object Model),即文檔對象模型,是 HTML 和 XML 文檔的編程接口,是 Web 中的概念。Weex 的運行環境以原生應用為主,在 Android 和 iOS 環境中渲染出來的是原生的組件,不是 DOM Element。
Android和iOS原生環境中不支持 Web API,沒有 Element 、Event 、File 等對象。不支持選中元素,如 document.getElementById 、 document.querySelector 等;也不支持基于 DOM API 的程序庫。
Weex 支持在標簽上綁定事件,和在瀏覽器中的寫法一樣,但是 Weex 中的事件是由原生組件捕獲并觸發的,行為和瀏覽器中有所不同,事件中的屬性也和 Web 中有差異。
BOM(Browser Object Model),即瀏覽器對象模型,是瀏覽器環境為 javascript 提供的接口。Weex 在原生端沒有并不基于瀏覽器運行,不支持瀏覽器提供的 BOM 接口。
沒有 window 、screen 對象
Weex 中并未提供瀏覽器中的 window 和 screen 對象,不支持使用全局變量。如果是想要獲取設備的屏幕或環境信息,可以使用 WXEnvironment 變量,可獲取信息具體如下:
沒有 document 對象
在瀏覽器中 document 表示了當前活動的文檔模型,在 Android 和 iOS 環境中并沒有這個對象,也不支持與其相關的 DOM 操作。
沒有瀏覽器中的 history 、location 、navigator 對象
在 Android 和 iOS 中也有“歷史”和“導航”的概念,但是它是用于多個管理視圖之間的跳轉的。在瀏覽器中執行“前進”、“后退”仍然會處于同一個頁簽中,在原生應用中“前進”、“后退”則會真實的跳轉到其他頁面。
Weex 也提供了 navigator 模塊來操作頁面的跳轉,該navigator與瀏覽器中的navigator不同,通過weex.requireModule('navigator')引入。
在 Weex 中能夠調用移動設備原生 API,使用方法是通過注冊、調用模塊來實現。其中有一些模塊是 Weex 內置的,如 clipboard 、 navigator 、storage 等。
為了保持框架的通用性,Weex 內置的原生模塊有限,不過 Weex 提供了橫向擴展的能力,可以擴展原生模塊。
Weex的官方文檔說,Weex0.28.0版本開始JavaScript解析器被分離出來,如果我們直接按照官方文檔里來弄, apk是跑不起來的。
會報錯誤提示libjsc.so包找不到,然后程序就閃退了。
根據官方對Weex0.28.0版的說明,只需要將上圖中的代碼放到主項目的build.gradle里,它就會為我們的項目自動下載需要的文件。
于是,我按照官方的方法來配置,但是,發現又提示錯誤:
Certificate for <raw.githubusercontent.com> doesn't match any of the subject alternative names: [default.ssl.fastly.net, fastly.com, *.a.ssl.fastly.net, *.hosts.fastly.net, *.global.ssl.fastly.net, *.fastly.com, a.ssl.fastly.net, purge.fastly.net, mirrors.fastly.net, control.fastly.net, tools.fastly.net]
簡單來說就是這個地址訪問不到。上網搜也搜索不到如何解決。所以我先把jsc-android這個包下載下來,
然后把它直接放到項目里的這個目錄下
并把download_jsc.gradle文件下載下來,這個文件就是
https://raw.githubusercontent.com/apache/incubator-weex/release/0.28/android/sdk/buildSrc/download_jsc.gradle
這個地址的文件,通過上面這個配置無法加載到這個文件,我通過其他渠道下下來了,我將文件放到如下圖的位置中
然后再build.gradle里配置
然后重新make project項目就不會閃退了。
Weex0.28.0版的說明:
https://weex.apache.org/download/major_change.html#_0-28
jsc-android-241213.1.0.tgz下載地址:
https://download.csdn.net/download/lgywsdy/12267774
項目下載地址:
https://download.csdn.net/download/lgywsdy/12267811
多深度文章,歡迎訪問云計算頻道:https://yq.aliyun.com/cloud
摘要:在2017年1月12日 Weex Conf 2017上,阿里巴巴商家事業部無線千牛團隊的無靈結合阿里巴巴無限商家端的實際業務分享了Weex在千牛開放中的應用實踐,本文分享了面對業務的各種挑戰,無線千牛團隊是如何一步步轉向Weex的,以及在實際過程中遇到挑戰和所做的努力。本文是無靈關于Weex在千牛開放中的應用實踐的分享整理。
本文整理自演講嘉賓的分享視頻以及PPT。
本次分享將主要介紹Weex在千牛開放平臺中的一些應用實踐,今天分享的內容主要分為以下四個部分:
千牛當前的業務場景與挑戰
為什么選用Weex作為解決方案
基于Weex解決方案,我們還做了什么
目前isv使用改造后的效果的前后對比與當前的進展
首先來介紹一下千牛當前的業務場景。大家可能對于千牛的客戶端不太熟悉,其實千牛是一個面向商家的移動客戶端。千牛主要是面向淘寶商家的一站式管理店鋪以及辦公的工作平臺,下圖中的右側圖片就是千牛客戶端的一張截圖。
淘寶的商家可以在千牛平臺上進行客服接待,管理自己的店鋪,以及看數據報表等,最重要的一點就是商家還可以完成與自己店鋪相關的所有的工具鏈路的支撐,比如交易管理的工具以及服務、商品管理的交易和服務等。這些服務與管理都是由千牛平臺的isv提供的,因為isv能夠根據用戶的行為為用戶提供多種多樣的定制化服務,所以這部分我們交給了isv去實現。這樣就基本構建起千牛的整體工作平臺。為了實現這樣的一站式工作平臺,千牛提供了開放的插件體系來幫助isv開發出更加豐富的工具。除此之外,千牛平臺還對于用戶進行了畫像,用戶將根據畫像被歸納到不同的用戶域以及不同角色下面去,實現使得不同的用戶所看到的工作臺都是不同并且動態變化的,并且將為不同的用戶提供不同的功能。
接下來解釋一下插件的應用場景。千牛是一個數據驅動的平臺,當淘寶的一條交易訂單的數據發生變化之后,系統就將會收到一條消息,這條消息就將推送到千牛的客戶端,之后客戶端的數字區域就會發生變動。當用戶發現有在客戶端上有數字發生變動或者接收到了新消息的話,通過點擊數字或者消息就可以跳轉到isv的插件中去,之后就由插件完成由isv提供給用戶的一些具體的工作,比如查看訂單的具體詳情,或者復制訂單的發貨的具體地址以及修改商品價格等一些相關的功能,這些功能都是在由isv提供的插件的內部完成的。在插件完成業務的處理之后,將會跳轉回千牛的模塊,進行比如像旺旺的接待或者溝通,在接待完成之后再跳轉到isv的插件里面繼續進行處理。而對于用戶而言,看到則是整體的對于千牛客戶端的操作流程,但是在千牛內部其實是先從千牛跳轉到isv的插件應用,之后再跳轉回千牛這樣的一個分為三步的動作。所以isv所提供的插件的穩定性和用戶體驗的一致性都將會是一個需要我們關注的問題。
接下來是對于多角色多用戶域的展示,通過下面的兩張圖片可以看出,千牛的工作平臺針對不同的用戶提供的服務和展現的界面是不一樣的。在所有的工作臺里面,在所有的O2O場景下,可能用戶看到的是像左邊這樣圖片的界面,在這樣的界面里不會有太多的數據,而且將會突出其比較重要的工具。而對于企業的老板而言,更關心的可能是企業的訂單數量等的與企業業務相關的數據。所以對于不同的用戶域以及不同的用戶角色而言,千牛的客戶端都是需要進行動態構建的。
那么在使用Weex之前,千牛提供的是什么呢?其實之前,我們將平臺分為了四層,首先是設備能力層,也就是將千牛的設備能力,比如拍照、網絡、存儲以及定位等基礎的能力通過容器層進行開放。將這些能力開放給isv,之后通過容器層將isv的業務代碼與千牛的代碼進行相互溝通并呈現出來。再上一層則提供了MSUI組件庫和離線包系統,離線包與之前提到的資源預加載的東西差不多。最上層就是千牛的業務能力層,在這一層會將千牛所能夠提供的全部的商業能力進行了抽象并且以API的方式進行輸出。這樣一來,isv就可以通過API的調用來使用千牛官方所提供的能力,比如像改價、退款、支付以及旺旺接待等功能。
千牛所面對的挑戰又是什么呢?其實大家都知道,在H5的開發方式下需要面對幾個比較大的挑戰,一個挑戰是網絡,網絡對于isv的影響是巨大的;另外就是動畫,其實isv比較難于實現一些與native相近的交互性的動畫;第三個挑戰就是安全問題,因為針對于一些運營商的劫持問題將會極大地困擾isv。除此之外,isv本身存在的問題也是需要面對的挑戰,因為isv自身水平也是有高有低,參差不齊的,比如有一些isv能夠將網絡和動畫問題解決得更好一些,能實現接近于native的交互式用戶體驗,而對于技術差一些的isv則往往不能實現。
另外一個方面的挑戰就是isv的發布問題。因為isv可以對于自己的插件直接在服務器端進行發布。也就是說isv一旦入駐千牛平臺,那么它的插件想更新什么就可以更新什么,如果isv在自己的插件中掛一個廣告或者活動頁面,即便是極大地損害了用戶體驗,但是平臺也對其沒有太大的管控力和約束能力。所以對于千牛平臺而言,如何提高對于isv的管控能力也是非常大的挑戰。另外就如同之前展示過的,千牛平臺的動態性也是非常強的,所以需要針對于不同的用戶域去展示不同的用戶形態。以上這些就是千牛需要面對的挑戰。
那么我們為什么選用Weex呢?其實在接入Weex之前,我們也進行了一些在React Native上面的嘗試。在React Native方案提出之后,我們認為這個方案非常好,能夠在很大程度上解決我們當時的開發方式所帶來的問題。所以在2015年11月份的時候,我們就開始對于自身的業務代碼進行試用,經過驗證發現能夠滿足在比如長列表加載速度等問題上面的要求,所以在2016年3月份的時候就開始嘗試封裝起來,并且將框架提供給isv。但是在開發和接入的過程中,不斷地暴露出了問題,所以最終不得不切換了跑道,投入了Weex的懷抱。
接下來和大家談一談我們在React Native里面遇到的問題。第一個是性能問題,隨著業務的逐漸復雜,Bundle包的大小將會成為比較大的問題,而且Bundle包會不斷地進行膨脹,所以需要花費大力氣去進行優化。更可怕的是Bundle包的大小會直接影響加載的速度,我們曾經做過一個對比試驗:當業務足夠復雜,Bundle包足夠大的時候,首次加載的時間甚至要比一個Webview加載的時間還要長。另外就是React Native自身的問題,比如像是核心組件Listview中的cell復用的問題將會影響內存開銷以及性能。當然今天看來可能這些問題都有了一些解決方案,但是在當時對于我們而言,的確是一個巨大的挑戰。
React Native的另外的一個問題就是內存消耗,因為每個插件都是獨立的環境,所以需要對于實例進行頻繁地創建和銷毀,所以對于內存的消耗將會是巨大的。
第三個問題就是端的差異性。React Native所強調的是Learn Once而不是Write Once,所以也就是說無法讓isv去關心平臺上的差異,消除端差異的工作只能交給平臺自己去進行處理,但是這些問題都不是不可以逾越的。而最終讓我們放棄React Native的是它的Breaking Change問題,因為React Native是一個發展非常迅猛并且更新頻率非常高的框架,在我們接入的那個階段,React Native基本上一到兩周就會更新一次,而兩次更新基本上就會出現一次Breaking Change問題,而這個問題將會給我們帶來非常大的挑戰。因為如果只是使用React Native開發自己的業務,可能不會出現太大的問題,但是使用React Native來構建平臺供其他的isv使用,那么Breaking Change問題將會使得開發者非常頭疼。如果每次變化都需要通知平臺所有的isv進行版本更新或者升級,這個成本也將會是無法承受的。
因為以上的原因,Weex走進了我們的視野。Weex吸引我們的有以下幾點,首先是版本升級的向前兼容,Weex團隊承諾框架的向前兼容性。第二點就是Weex具有多端的一致性,這樣就不需要我們自己再去處理多端的一致性問題了。Weex的第三個優點就是輕量,并且支持能力的可插拔,而且具有便利的拓展性,Weex提供了基礎的能力,但是這些能力并不一定能夠滿足每個業務場景。而且對于像千牛這樣的面向商業的業務場景而言,需要有更多的面向自身的業務上的考量,所以這個框架是否是能夠非常方便地替代,是否能提供基礎的能力以及拓展能力是我們非常看重的,而Weex在這塊做的非常好。另外一方面就是Weex解決了React Native自身的一些性能問題,比如Bundle運行環境的共享,Listview的復用問題也解決的非常不錯。最后一方面就是Weex能夠靈活地支持多種前端框架,而且不需要切換前端框架,因為我們之前在React Native上做了大量的工作,如果不能實現平滑過渡的話,對我們而言也會造成很多麻煩,而Weex卻能夠幫助我們平滑地進行遷移。
至于我們借助Weex做了些什么工作,其實在QAP2.0時代,我們主要在三個方向上開展工作。第一是針對插件APP打開主鏈路進行了優化;第二個就是針對于新的開發方式提供了更豐富的并且更適合千牛的能力;第三個則是在引入了新的框架之后,希望幫助千牛平臺上的isv能夠以更加友好的方式進行遷移并且盡快熟悉新的框架。
于是產生了如下圖所示的框架。客戶端這邊的基本分層是沒有發生變化的,在容器層加上了Web容器,除此之外還做了一些容器打通的相關工作,比如使得在Weex容器里面可以無縫地使用原來為isv開放的Web容器,這樣的web容器既可以被當做導航頁面進行處理也可以作為組件進行處理。另外就是針對于新的開發方式提供了一些新的framework,比如包管理的相關機制,并且提供了更加native方式的儲存機制以及數據采集、導航、管理以及插件生命周期的管理等。除此之外,我們還提供了一套完整的與開發相關的工程管理上面的工具,工程管理工具的目的主要是在安裝、打包、發布這一系列流程中遵守千牛的包規范和格式,并且也為isv提供了一些開發調試的工具。
接下來回到插件APP打開主鏈路優化這個話題上來。我們把主鏈路優化分為三個環節,分別是:資源加載、數據加載以及頁面渲染。
對于資源加載而言,在QAP1.0的時候,我們提供給isv的是使用本地資源鏈接網絡請求的能力。當插件容器發起一個請求的時候,傳統的方式是直接向isv的云端去請求資源,而在QAP1.0提供了離線包的機制,插件容器可以先去請求離線資源包,看看資源包里面是否有所需要的資源,然后可以將相關的資源通過千牛的云端下發到客戶端,這就是QAP1.0的資源加載機制。QAP2.0版本則完全廢除了插件容器直接向isv請求資源的這條鏈路,而只有在服務降級時,才會有可能使用這條鏈路。所以新的開發方式對于包的管理的要求是非常嚴格的,之前資源包還可能是可有可無的,因為實在不行還可以通過網絡請求資源,但是QAP2.0將資源包升級成為了應用程序,也成了插件容器請求資源的主戰場,相比之前資源包里面基本都是JS或者CSS這些靜態資源而言,QAP2.0版本的資源包里面還有很多配置文件,可以將具體的能力或者安裝包的動作配置到資源包里面。
大家可以看一下QAP2.0中包的結構究竟是什么樣子的。包主要又兩部分構成,第一部分就是資源目錄,另外一部分就是配置文件。
資源目錄里面存放什么內容呢,其實就是每個配置的Bundle包,以及靜態的資源圖片以及icon這樣的資源。而對于配置文件來說,也分為了三個部分,首先是APP相關的配置,存儲了APP配置基礎的一些信息,比如插件的AppKey、容器的相關信息、引入的NUKEUI、QAPSDK版本以及默認的應用啟動頁等等;另一部分就是APP的能力宣稱配置,其實在數字區域的背后都是對應著一個插件,我們將數字的對應行為進行了業務上的抽象,并且提煉出不同的能力交由isv進行實現。如果isv要實現某一個業務,那么需要告訴客戶端當觸發某個插件的能力時將會喚起這個插件來幫助客戶端執行這個工作,也就是將APP的能力進行聲明,并與外部的能力路由進行對接。第三個是資源配置,當程序包安裝和下發到本地的時候,就會去讀取資源配置中的配置表,將資源下發到正確并且適合的位置上去,這個位置對于開發者是透明的,但是會極大地方便平臺的管理。
談完了資源加載,我們接著聊一聊數據請求。談到數據請求,先要談一談isv在之前開發過程中所遇到的問題。一個isv想要完成一個業務其實需要調用多個API才能拿到想要的結果,此外為了保證數據的及時性,需要經常進行拉取。由于不知道數據什么時候更新,所以每次都需要拉取,這樣的方式導致緩存的利用率比較低。并且之前的架構中緩存需要考慮用戶隔離,大小的限制等問題,所以導致使用會變得非常麻煩。
接下來分享一下在QAP上提供了什么樣數據請求等待優化方案。QAP獲取數據并不是通過自己去獲取數據的,而是通過淘寶的top平臺去獲取數據,所以我們做了top請求的長連接代理,使用TCP的長連接解決了HTTP的多路復用等時間上的消耗過多的問題,除此之外還使用了web瀏覽器自身提供的存儲能力。
在QAP2.0中,我們引入了批量的top請求,也就是把多個請求進行批量發送以及批量接收。另外就是對于數據推送方面,在TCP長連接中有一個數據推送通道,在QAP2.0將這個數據通道開放給了isv,isv可以將自己的重要數據實時地推送到客戶端,這樣就不用每次都要去拉取想要的數據了。而且對于多用戶的數據實現了天然的隔離,并且提供了批量存儲的接口。
在頁面渲染部分,我們做的工作相對比較少了,主要是交給其他團隊提供支持。在QAP1.0階段使用了MSUI+Webview,在QAP2.0階段使用了NukeUI+Weex。這里稍微談一下NukeUI的優點,NukeUI有更加規范的UI交互,并且提供了千牛組件開發的規范,還具備主題換膚能力,也提供了更優秀的性能。
在做完這些事情之后,在將組件推出并將QAP進行打包的時候還是遇到了很多問題。其中一個就是包大小的問題。目前千牛平臺上的插件功能多并且非常復雜,isv開發后的頁面不像是運營頁面那樣,而是可以視作APP的由多個頁面組成的程序,所以包大小難以控制。另外就是每個千牛的用戶平均擁有20多款的插件,插件安裝包非常多,如果包的大小沒有得到很好的控制,對于用戶的流量和空間都將會造成巨大的消耗。而Bundle包的大小在一定程度上也會影響插件的性能。Bundle包主要包括這樣的幾部分,rax、組件以及SDK,所以我們可以看到對于每個包而言,公共的部分是非常多的。雖然rax是按需打包的,但是隨著業務越來越復雜,一個APP幾乎能夠覆蓋組件庫中的全部組件,所以這部分是可以作為公用部分抽取出來的。
所以我們的解決方案就是將公用部分抽取出來放入Main.js里面,Main.js是Weex的運行環境,我們將其內置到Weex的運行環境中去。將公用部分抽取出來之后,Bundle包里面就只剩下了isv的業務代碼了,這樣使得包的大小能夠很好地控制。當然這樣的做法所帶來的比較大的挑戰就是內置包的版本管理和更新升級問題。因為Weex容器的初始化時機是在程序APP加載的時候,這樣的方案是沒有辦法在程序運行的期間做任何處理的。
我們目前正在努力的方向和希望解決的問題就是內置包的管理以及動態升級的問題,這個問題的解決需要Weex框架進行支持。Weex最近提出了Server的概念,允許在插件打開之前構建如圖這樣的一個環境,將內置包運行在這個環境里面,如果配置環境中配置信息與客戶端的版本號一致的話,就去默認地構建環境,如果不一致就會動態地對于出現問題的包進行更新,這樣就可以解決內置包的管理以及更新問題。
千牛還提供了更加豐富的能力。在通訊機制方面,這里的通訊機制主要是針對頁面級別以及整個插件的生命周期的機制。首先劃分的Page級別,也就是單個Bundle內部的事件通訊;其次是插件APP級別的事件通知,也就是插件APP下所有的Bundle之間進行的通訊;第三個就是千牛應用級別的事件通知,會把千牛主體應用發出的全局事件,比如前后端的切換,網絡變更等的事件通知給開發者。另外我們還提出了黏性事件的概念,就是當事件沒有被消費的時候不會丟失,避免在某些場景出現了事件發出了,但因為還沒有注冊導致接收不到的情況。
AppIndex主要是解決能力宣稱和能力路由的問題,整個插件能提供哪些能力,怎樣進行路由都由AppIndex進行管理的。首先對于一個插件而言,它可以將自己對應的能力錄入到能力路由表中,并且注冊到AppIndex客戶端體系中,當進行能力路由的時候會通過權限管理以及能力路由找到實現這個能力的插件,并根據路由表找到具體的頁面。其實在QAP1.0就有了這樣的一套機制,但是當時只能夠返回程序主入口的地址,而在QAP2.0就能精準地定位到每一個頁面。
為了精確地尋址,在千牛的客戶端中提供了通用的QAP的URI,所有的QAP頁面都是通過下圖中的這一套URI機制進行尋址的,通過這樣的URI就能夠定位到每一個頁面。
最后為了降低isv的遷移成本我們也做了很多事情。我們實現了Weex+Web的混搭,也就是在前期推廣的時候允許isv改造自己的部分頁面,也就是將自己的插件的入口頁面以及對性能有高要求的頁面進行Weex更改,其他要求不高的頁面還可以使用Web,這樣就能夠降低isv的開發成本;除此之外還為isv提供了業務開發實例和開發文檔以及一站式的開發工具。
對于開發工具而言,我們提供了QAP的CLI,能夠實現創建工程并且導入示例工程、進行調試、打包上傳、安裝真機測試以及獲取最新千牛測試包等功能。但是在將CLI提供給isv的時候也發現了一些問題,比如往往會遇到的平臺環境的問題以及依賴安裝緩慢的問題。
考慮到以上的問題,我們目前正在做的事情就是將整套相關依賴做成IDE,這樣開發者就可以在IDE里面進行一站式工作,可以很方便地找到入口、創建工程并且進行工程調試以及一鍵安裝和上傳。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。