談一個項目中的架構吧,在我們的項目中,視頻播放是一個非常重要的模塊,其業務形態也是多種多樣的,而且業務形態變動頻次也非常的高,當前版本是A方式,下一個版本就可能變爲B方式,如何才能適應該情況的,我們需要一個兼具彈性、可讀、可維護、易擴展、穩定的框架。
先說一下該框架之前的開發模式:
在我們的項目中的,涉及播放的包括:列表流式播放、詳情頁播放、小窗播放、全屏播放(分兩種:橫屏全屏和豎屏全屏),可能的觸發播放的方式包括:點擊播放,滑動播放,拉起詳情頁後自動播放,由半屏播放點擊全屏按鈕切爲全屏播放,直接打開全屏播放。爲實現前面所述業務形態,在項目前期採用的方式是具體業務具體實現,抽取通用的視頻播放模塊。結構圖如下所示:
其缺點是相當明顯的:
a.除播控及VideoView外,其他的播放邏輯均分散在各業務模塊中,代碼冗餘度高,代碼差異大
b.業務分散導致與播放相關的邏輯業務開發人員均需理解並掌握播放邏輯,增加了開發成本及維護成本
c.業務邏輯耦合度高,導致新業務加入困難,意味着項目的擴展性差
d.bug數量一樣居高不下,穩定性差
因此,抽象通用的播放框架迫在眉睫。
方案包括以下幾項:
1.提取多種播放形態:
(1)列表流式播放--橫屏
(2)列表流式播放--豎屏
(3)豎屏全屏播放
(4)橫屏全屏播放
(5)半屏播放下部帶信息
2.提取三個控件類,結構如下所示:
(1)VideoPlayWrapView的作用爲:
a.提供可以接受各業務的統一容器,消化不同的業務決定子Fragment呈現的具體外在形態,可能不太好理解,舉個例子:接受到的業務要求爲列表流式播放,則VideoFragment的呈現形式爲半屏,下部的VideoDetailContainerFragment爲隱藏狀態。
b.對外封裝統一的事件響應,對內區分分發的子View
c.統一封裝各業務的回調,發往外部
(2)與播放相關的封裝位於VideoFragment,其功能包括以下幾條:
a.盛放播放控件VideoView及播控
b.與播放器相關的邏輯(開啓、關閉、暫停等)
c.響應外部條件變化對播放的影響(如網絡、電池等)
d.播控上提供的功能
(3)VideoDetailContainerFragment是一個插件,該處可以替換爲別的模塊,由業務方決定,在播放窗的下方放置什麼業務模塊。
3.提取統一的業務處理功能,包括以下幾類:
a.播放
b.暫停
c.停止
d.VideoDetailContainerFragment展開(動態效果)
e.VideoDetailContainerFragment顯示
f.VideoDetailContainerFragment隱藏
g.其他業務支持(如系統權限相關)
上述的業務處理功能統一使用常量命名,業務方只需負責發送業務分類。在統一的播放模塊中不區分來源,只區分業務本身,取不同的處理方式,實現了業務與處理的分層隔離
4.統一規劃與手勢相關(點擊、滑動)的事件分發邏輯,上層的Fragment、Activity負責接受事件,然後傳遞給VideoPlayWrapView,由VideoPlayWrapView決定分發給那個子佈局處理
5.權限處理邏輯提供基本功能,是否觸發由上層業務決定
最終的框架圖爲: