天天看點

「商業移動端」開屏重構

作者:閃念基因

項目背景

1、開屏廣告,是商業用戶端維護的最重要子產品,有,,,,,等特點。

2、商業早期開屏廣告功能單一,實作随意,多處違背基本設計原則,更沒有系統的進行架構設計,80%的代碼堆砌在少數幾個類中。

3、随着,,,人力無法滿足業務deadline時的,,。目前開屏子產品已接近無法維護,煙囪化嚴重,研發測試成本翻倍,品質瀕臨失控,性能肉眼可見的日益劣化。

重構目标

核心意圖:管理複雜度,建設為獨立商業能力,角色由面向頁面的,轉向面向接口的。

重構收益:

1、提供開屏服務,獨立元件、可獨立運作。

2、可插拔式UI插件庫設計。

3、調試速度大幅提升,從運作一次應用10分鐘左右,提升至30秒左右,提升95%。

4、無用、過期代碼下線,包體積縮小100k左右。

5、去煙囪化,多套開屏邏輯統一,獨立元件高速調試,開屏開發周期縮短30%以上,故障率減少50%以上,QA測試周期縮減50%以上。

6、優化開屏耗時200ms,開屏展示率提升3%。

7、獨立商業能力之一,可為任何業務,任何知乎app,直接提供插屏廣告能力。

開屏子產品現狀

現有問題&代碼性能評估

重構前梳理:Android 開屏廣告梳理

對梳理過程中,代碼現存具體問題進行歸類,總結,進而進一步評估代碼性能現狀。

結論:現有開屏架構不能滿足商業日漸複雜的開屏場景,與日俱增的開屏收入。重構時需重點關注可讀性、可維護性、可複用性。

「商業移動端」開屏重構

可讀性

「商業移動端」開屏重構

可拓展性

「商業移動端」開屏重構

可維護性

「商業移動端」開屏重構

可複用性

「商業移動端」開屏重構

代碼性能

設計原則比對

結合代碼性能現狀,評估設計原則比對度,找出重構側重點及方向。

結論:重構設計中,重點關注SRP、LKP、OCP、DIP四個指導性原則上的優化。

「商業移動端」開屏重構

代碼結構

核心類 LaunchAdFragmentDelegation 現狀,70%功能堆疊在一個類中,20%功能與該類有關

「商業移動端」開屏重構

現有架構

頁面級開發,即每個頁面有自己的一套開屏邏輯,一個需求點,多倍工作量,且難以保持一緻性。

「商業移動端」開屏重構

縱向與橫向(架構與切面)

縱向:

如上面簡易架構圖,目前縱向縱深不夠,整體是一個拍平的狀态。基本的UI層、資料層、邏輯層、核心層結構都不具備。UI層和邏輯層在一處,且或多或少包含資料層及核心層邏輯。

橫向:

目前關鍵節點間途徑若幹方法或回調,其間散落了大量各方面邏輯,不成體系,難以了解,且任何一處出錯都會打斷開屏邏輯,沒統一管理。

「商業移動端」開屏重構

架構設計

理念

1、核心思想為将開屏廣告子系統「SDK化」,抽象為一種商業能力,面向API開發、維護。

2、SDK内部隻包含通用功能,高穩定性,高可拓展性,不關注具體業務場景。

3、縱向架構層級上講究「動靜分級」。

4、橫向切面分割上講究「統一精準」。

5、于使用方而言,内部實作黑盒,高度可配置,可插拔,可自定義。

商業整體架構圖

「商業移動端」開屏重構

開屏子產品架構圖

「商業移動端」開屏重構

SDK 層:

抽象出和業務完全無關的 SDK 層,面向接口設計,可為知乎App,來鴨App,知乎日報App或外公司App提供開屏廣告接入支援。

基建層:

基礎能力,日常開發時無需修改。

架構層:

将通用業務、共性代碼等低頻率修改代碼獨立出來,形成架構層,這層代碼是可由專人維護,其他業務線同學無法修改。

拓展層(Api):

處于元件api中間件之中,對外提供兩套接口,一套為指令式,控制開屏廣告;一套為響應式,接收開屏廣告各類回調。

接口設計:

ZHSplashAd:

    • 構造方法:ZHSplashAd(Activity activity, String posId, ZHSplashAdListener adListener)
    • fetchAd() 拉取廣告,配合showAd使用,實作和fetchAndShowIn相同的功能。
    • showAd(ViewGroup container) 展示廣告,配合fetchAdOnly使用
    • addViewPlugin(SplashPlugin plugin),添加自定義插件
    • removeViewPlugin(),删除任意開屏插件
    • isLaunchAdShow() 開屏廣告展示條件是否滿足

ZHSplashAdListener:

    • onNoAD(AdError error) 廣告加載失敗,error 對象包含了錯誤碼和錯誤資訊,錯誤碼的詳細内容可以參考文檔第5章
    • onADDismissed() 廣告關閉時調用,可能是使用者關閉或者展示時間到。此時一般需要跳過開屏的 Activity,進入應用内容頁面
    • onTimeOut()熔斷時間内,開屏廣告未就緒
    • onADClicked() 廣告被點選時調用,不代表滿足計費條件(如點選時網絡異常)
    • onADExposure() 廣告曝光時調用
    • onADTick(long millis) 倒計時回調,傳回廣告還将被展示的剩餘時間,機關是 ms
    • onADLoaded(long expireTimestamp) 廣告加載成功的回調,在此方法中調用SplashAD.showAd(ViewGroup container) 方法,即可展示廣告。

業務層:

SDK層的使用者。如超級首映,冷啟動開屏,熱啟動開屏,端内開屏等,知乎創新産品App等。

元件化設計

重構前開屏代碼并不獨立,處于ad元件中,,,其他業務線元件直接調用,,且。

重構前元件圖:

「商業移動端」開屏重構

重構後新增launch元件,并伴生luanch-api中間件,面向接口程式設計,與其他業務線解耦,可獨立編譯(開發現狀:跑一次主工程10分鐘。可獨立編譯後,開屏需求跑一次隻需要1分鐘,大幅提升人效)

重構後元件圖:

「商業移動端」開屏重構

具體實作

響應式程式設計

重構前,由于開屏場景,多線程,阻塞,等待,資料轉化場景複雜且豐富,皆采用回調的方式實作,造成了現在的“回調地獄”,代碼可讀性,可維護性很差。

重構後,采用rxjava,響應式程式設計方案。基于觀察者的實作原理,豐富的操作符支援,使得開屏邏輯主幹流程在100行代碼以内實作,一目了然。

「商業移動端」開屏重構

主流程時序圖

「商業移動端」開屏重構

開屏展示條件

重構前:

跳過方式:實作接口的方式跳過開屏

「商業移動端」開屏重構

重構後:

跳過方式:采用apt注解處理器的方式,利用編譯期來标記不展示開屏的Activity,實作跳過開屏

「商業移動端」開屏重構

資料流、資料結構設計

重構前:

多套資料結構來回轉換,重複指派,容易造成記憶體洩漏,可讀性差,浪費性能。

「商業移動端」開屏重構

重構後:

單資料結構Advert一以貫之

圖層插件設計

開屏插件庫:

開屏廣告所需UI元素,皆以自定義view形式建構,并加入插件庫,随時插拔。

「商業移動端」開屏重構

預設渲染流程圖:

「商業移動端」開屏重構

預設渲染的插件:

「商業移動端」開屏重構

自定義插件預設處于最上層,可設定事件是否透傳。

發射井設計

下發的多個開屏廣告同時并發執行,抽象為發射井模型,設計上關注比對、優先級、發射、傳回隊列、時限等。

流程圖

「商業移動端」開屏重構

等待隊列設計

「商業移動端」開屏重構

類圖

「商業移動端」開屏重構

作者:知乎商業移動端團隊-于铠瑞

出處:https://zhuanlan.zhihu.com/p/593000564

繼續閱讀