龍崗公司

    移動端SDK的優化之路

    日期:2017/12/14 人氣:172895
    導讀: sdk優化過程,是一段血淚史,能夠吐槽的當地許多。移動端sdk不像app一樣便利,sdk發布后呈現任何問題,都會影響到許多家的app。不能像一家app一樣,能夠及時發布一個hotfix,或許強制升級app,又或許熱更新app。所以sdk發版之前,有必要通過嚴厲的測驗,每一次sdkhotfix的發布都會對我們的用戶形成嚴峻的影響。sdk的優化,最大的痛點是它的巨細。每次對接客戶,他們都會

     sdk優化過程,是一段血淚史,能夠吐槽的當地許多。移動端sdk不像app一樣便利,sdk發布后呈現任何問題,都會影響到許多家的app。不能像一家app一樣,能夠及時發布一個hotfix,或許強制升級app,又或許熱更新app。所以sdk發版之前,有必要通過嚴厲的測驗,每一次sdkhotfix的發布都會對我們的用戶形成嚴峻的影響。

    sdk的優化,最大的痛點是它的巨細。每次對接客戶,他們都會問我們sdk的巨細是多少?每逢說到iOSsdk時,他們都會說還蠻大的,他們自己家的app都現已幾十M了,接入我們的sdk會添加他們app的巨細。所以,不得不開端苦楚的sdk優化之路。

    我們首要從以下幾個方面進行優化sdk:

    1. 腳本構建

    2. 極限優化(網絡、日志上報、圖片格局等方面優化)

    3. 第三方組件替換

    4. 小版別穩步迭代

    腳本構建

     

    我們從開端開發sdk到現在正在開發中的3.8版別,一向推重憑借腳本進行主動化打包,例如android運用gradle。憑借腳本的優點在于:

    1)androidsdk混雜

    2)主動生成文檔,便于開發者查閱,例如android能夠很便利的生成javadoc文檔

    3)androidsdk上傳aar包,iOSsdk發布到cocoa-pods,便于開發者集成

    4)節省人工時刻,削減犯錯

    腳本一般能協助我們完成許多主動化的工作,能進步工作效率的辦法是必定會被選用的。

    接下來我們來看看憑借gradle怎樣完成sdk混雜,中心的task是proguardJar這個task。

     

    極限優化

     

    所謂極限優化,是指從多個視點、維度對sdk進行優化,重點是考慮網絡優化以及電量耗費優化。能夠做到代碼精簡,低網絡流量,微能耗而不僅僅是低能耗。

    香農定理是所有通信制式最基本的原理,我們知道C=B lb(1+S/N)

    其間:C是信道支撐的最大速度或許叫信道容量,B是信道的帶寬,S是均勻信號功率,N是均勻噪聲功率,S/N即信噪比。

    從開端的1G網絡到現在的4G網絡,都是在利用這個公式進步速度。要么充分利用頻道資源,要么進步全體帶寬。可是頻段資源都是有限的,所以不得不擬定出更優異的戰略來進步資源的利用率。結合網絡狀況、手機電量等要素,我們采納以下幾種辦法進行優化:

    1)兼并網絡懇求,削減服務器壓力和dns懇求時刻,削減手機的網絡流量。

    2)數據緩存到本地,最省電的辦法就是不運用移動網絡,數據緩存能大大削減網絡懇求的次數。

    3)日志上報戰略,批量非實時上報。日志生成后,首先存儲在RAM中,根底戰略是滿30條發送,每隔一分鐘輪詢一次。為了滿意客戶定制需求,發送戰略可通過后臺裝備。如果遇到反常狀況,比方網絡反常或許crash等,我們會將日志存儲在本地sqlite中,在程序下次啟動后,依據發送戰略再次發送。

     

    為了削減app的網絡流量耗費,我們還將活動的圖片新增了WebP的格局。

     

    WebP格局的圖片優點是什么?舉個比方,做一個簡略的測驗比照PNG 原圖、PNG 無損緊縮、PNG 轉WebP(無損)、PNG 轉WebP(有損)的緊縮效果。

    能夠得出結論:PNG 轉WebP 的緊縮率要高于PNG 原圖緊縮率,相同支撐有損與無損緊縮。

    變換后的WebP 體積大幅削減,圖片質量也得到確保(同時肉眼幾乎無法看出差異)。變換后的WebP 支撐Alpha 通明和 24-bit 顏色數,不存在 PNG8 顏色不行豐厚和在瀏覽器中可能會呈現毛邊的問題。

    WebP 的優勢體現在它具有更優的圖畫數據緊縮算法,能帶來更小的圖片體積,而且具有肉眼識別無差異的圖畫質量。除此之外,國內外許多聞名的運用現已運用了WebP格局,這也是我們運用它的原因之一。

    在3.8版別的sdk中,用于活動的Marketing接口會回來PNG和WebP兩種格局的圖片。關于Android而言,如果操作系統版別在4.0以及4.0之后,它天然生成支撐WebP格局,sdk會優先加載這種格局,加載不成功才會去加載PNG的圖片。如果是Android 4.0以下,sdk只加載PNG圖片。

    關于iOS而言,現在iOS本身不支撐WebP格局(希望iOS10會支撐它:(),要憑借第三方庫才干支撐,比方SDWebImage。可是iOS sdk現已足夠大了,不行能把SDWebImage集成到sdk。所以,現在iOSsdk不會像androidsdk一樣存在imageloader,iOSsdk把圖片加載的權力交給開發者。當然今后,我們必定會給iOSsdk供給相似android的imageloader的功用。

    憑借Webp,我們替用戶節省了流量,節省了手機內存和CPU資源。

    未來,網絡懇求還會進一步優化。會考慮運用protobuf協議替換現在的回來json格局。protobuf回來的數據更小,而且是二進制的格局。從安全性的視點上說,在必定程度上能夠避免被歹意抓取數據包進行剖析。

    第三方組件替換

     

    關于移動端sdk的開發者來說,移動端其他的開發人員都是美好的。他們能夠嘗試運用許多的第三方庫,在github上每天都會誕生許多優異的第三方庫。sdk的開發者不得不自己去完成許多功用,由于考慮到sdk巨細的問題。

    關于sdk的開發者來說“這是一個最好的年代,也是一個最壞的年代”。他們有必要自己去“造輪子”,可是會給他們帶來更多收成,無論是接觸到os的底層仍是規劃方法,都會比一般的開發者了解更多。

    我們魔窗的sdk包含Androd、iOS版別在不斷迭代的過程中,都經歷過第三方組件的替換。以android為例,我們替換了json解析器和網絡結構等等。

    開端,我們運用fastjson,它是由阿里巴巴的工程師編寫的,功用和安穩性都很好。我自己寫app時,也會首選它作為json的解析器。可是它顯著增大了sdk的體積,所以我們運用gson替換了fastjson。用了一段時刻后,覺得gson仍是很大。

    終究,我們考慮重寫jsonparser。重寫的jsonparser,有必要能兼容原先gson的一些api,避免sdk工程做太大的改動,這是我們重寫的一個方針。

    重寫jsonparser之前,我們先對反射做了一次封裝。傳統的反射是這樣寫的:

     

    封裝之后的寫法是這樣的,依據流式API:

     

    依托于簡練的反射,完成了自己的jsonparser。除此之外,還需求將http懇求回來的成果憑借自己的json東西類變換成目標、目標數組。相似于這樣:

     

    憑借這個反射我們還取得的額定優點是,在android4.0今后的版別能夠隨時獲取到App的ApplicationContext,曾經還擔心獲取不到ApplicationContext,這樣一來還能避免memory leak。由于,Activity的Context運用不當經常會引起內存走漏。

     

    另一個被替換的第三方組件是volley。它是google開發的網絡結構,便于android運用操作網絡。替換volley的原因,是它功用太強大了,幾乎就是一個“全家桶”。我們用不到那么多功用,sdk需求的是一個契合本身事務需求的網絡結構。相同,替換的準則是能夠兼容原先volley的大部分api。所以我們做了一個簡化版別的volley,它大致的流程如下圖所示:

     

    它最首要的四個部分是:Request、RequestQueue、NetworkExecutor和ResponseDelivery。

    Request,即各種懇求類型。包含StringRequest和ImageRequest,別離表示回來的數據是字符串和網絡圖片的懇求。Request支撐Get、Post懇求,支撐header、支撐懇求緩存、支撐postbody、支撐懇求的重試機制。Request類還包含了一個回調處理的接口ResponseListener。

    第二部分為音訊行列RequestQueue,音訊行列保護了提交給網絡結構的懇求列表,而且依據相應的規矩進行排序。默許狀況下更具優先級和進入行列的次序來履行,該行列運用的是線程安全的PriorityBlockingQueue,由于我們的行列會被并發的拜訪,因而需求確保拜訪的原子性。

    第三部分是NetworkExecutor,它是網絡的履行者。該Executor承繼自Thread,在run辦法中循環拜訪第二部分的懇求行列,懇求完成之后將成果投遞給UI線程。為了更好的操控懇求行列,例如懇求排序、取消等操作,這兒我們并沒有運用線程池來操作,而是自行辦理行列和Thread的方法,這樣整個結構也變得更為靈敏。它的首要代碼是這樣的:

     

    其間,doRequest()辦法用于真實的網絡懇求和分發網絡懇求回來的Response。doRequest()支撐重試機制,它的大致流程如下圖所示:

    第四部分是ResponseDelivery,在第三部分的Executor中履行網絡懇求,Executor是Thread,可是我們并不能在主線程中更新UI,因而我們運用ResponseDelivery來封裝Response的投遞,確保Response履行在UI線程。

    總之,每個部分都契合單一責任的準則,便于日后的獨立保護。

    我們再看看怎樣憑借這個網絡結構怎樣調用httppost懇求。

     

    一. NeteaseAPM是什么

     

    關于一般的app開發來說,小版別快速迭代幾乎是不行或缺的辦法論。而關于sdk開發而言,“小步快跑,快速迭代”的戰略不再適用。我們有必要采納相對穩健的更新戰略。

    sdk是面向所有的開發者運用的,高版別有必要向下兼容api。如果某個api確實需求過期的時候,至少保存幾個版別后再刪去過期的api,并附有具體的說明文檔。

    關于sdk而言,版別發布也不宜頻頻,否則會讓開發者會感覺自己是“小白鼠”。這樣的體會,關于開發者是適當不友好的。

    關于每一個小版別除了新增的功用之外,我們都會集中精力優化好某一塊當地。每一個小版別都是“小步迭代”,可是通過幾個版別的迭代之后,仍是能夠完成質變。下面的表格是我開端接手魔窗sdk之后,androidsdk體積的巨細的變化。


    從3.0到3.7版別,android sdk的巨細,整體趨勢是不斷削減的。其實功用不斷添加的,sdk的安穩性也得到提高,這就是我們選用小版別不斷迭代帶來的優點。 

    未來,sdk拆分

    關于未來,我們尋求的是在確保sdk安穩的前提下,持續盡力削減sdk的巨細。將我們的sdk拆分紅多個組件,供用戶選擇自己想要的各個組件。我們現在sdk的模塊如下圖所示。

     

    sdk最中心的部分是sdkcore,它是sdk必不行少的組成部分。它有以下幾部分組成:

        1)http組件,是我們自己開發的http模塊,契合自己的事務需求。

        2)imageloader組件,在sdk中顯現活動圖片的組件,是自己開發的模塊。

        3)domain,是sdk所需求的目標,包含http回來的目標以及事務模型。

        4)config組件,是sdk有必要的裝備組件。

        5)jsonparser組件,json解析器,是我們自己開發的模塊。

        6)utils,sdk中各種協助東西類。

        7)sqlite組件,操作數據庫的相關類,把一些數據緩存到sqlite數據庫。

     其他的組件盡管沒那么重要,可是能夠通過自由組合的辦法,組成開發者想要的功用。這是我們未來1-2月的盡力方向——sdk的拆分。將sdk拆成更小更細粒度的模塊,開發者也能更好地選擇他們想要的模塊。

    比方一個開發者只想要tracking功用,那么他只需運用sdkcore包和tracking包。再比方一個開發者只想要mLink(依據deeplink深度改造)的功用,那么他會需求sdkcore包、tracking包、magicwindowview包和mLink包這幾個包。    

    文本來自采集文章 http://www.jreqjj.icu/26/324.html 如需轉載或刪除,請聯系管理員。

    1 2 3 4 5 6 7 8 9
    分享到:
龍崗網站建設
【龍崗本地網絡公司】——承諾3小時內上門服務!龍崗上門全國熱線:400-666-2014 粵ICP備12018349號 網站維護:深一深圳網站建設 【我要收藏此頁面】 網站地圖
全國龍崗注冊公司-服務網店
微信里卖什么最赚钱