1. 程式人生 > >如何更加安全、高效地選擇開源專案(內附詳解)

如何更加安全、高效地選擇開源專案(內附詳解)

前言

在平時的開發過程中,難免會遇到這樣那樣的難題,或者一些繁瑣且不想純手工完成的功能,對於這些問題,解決的姿勢有很多種,可以通過同事間的交流、上網查資料、去官網找文件等,隨著開源的推動和完善,尋找合適的開源專案支援,絕對是一個很好的方法。

如今市面上的開源專案魚龍混雜,並且有一些專案早已停止更新維護,跑demo的時候,怎麼用怎麼正確,一放入專案,卻發現哪哪都不合適,比如低版本下才可以執行,高版本刪去一些方法,再或者與一些新技術的包衝突等,在眾多開源專案中,我們應該以何種姿勢去選擇最佳方案?且聽我慢慢道來。

PS:目前我主要是做手機客戶端開發,以下的例子會舉一些日常開發的例子。

這裡寫圖片描述

正確理解、確定需求

“我喜歡蘋果,可是你給了我一車香蕉,然後你說你被自己感動了,問我為什麼不感動。我無言以對,然後你告訴全世界,你花光了所有的錢給我買了一車香蕉,可是我卻沒有一點點感動,我一定是一個鐵石心腸的人!我的人品確定是有問題的!我只是喜歡蘋果而已啊”。

對於這樣的問題,在我們的開發過程中也經常遇到,產品經理只是想要一個蘋果,而我們卻給他送來了一大包香蕉,後來發現哪哪不合適,又去和產品經理確定需求,才發現自己想的是錯的,相信這樣的例子,在每個人身邊都有過,因為沒有及時溝通,造成後期維護成本大大提高,如果發現的早還好,在面臨上線出現這樣的問題,這一定是晴天大霹靂。

正確理解、確定需求,對開發中選取第三方開源或者原生都是有很大幫助,可以大大降低後期維護成本。

前段時間公司要接入攝像頭來完成視訊直播功能,採用m3u8格式實現,後期也不會有其它格式接入,從開發者文件中看到,Android原生控制元件僅支援MP4格式,對於其它格式的相容,還存在很大問題,也就是說沒法完美相容m3u8。此時,我們僅需要找到m3u8格式支援的方案就好,在搜尋的征途中,我們大大地縮小的範圍。

相容性

做客戶端開發,對於相容性的話題,總是有千言萬語,從最初寫佈局到後來的整合,再到後來系統的升級,無時無刻不在與相容性打交道,尤其是在swift剛誕生的那一兩年,每個大版本都會大改api,這就有點扯淡了,搞的開發者心力交瘁,企業也不敢輕易嘗試使用。

對於佈局的適配的相容性,今天不做討論,接著上面視訊對接的話題繼續擼下去,經過一番對比,我把目標鎖定在了Google的ExoPlayer和bilibili的ijkplayer,這兩個都是開源專案,都可以在github找到原始碼,地址如下,點選可跳轉:

ijkplayer的github地址:https://github.com/Bilibili/ijkplayer

ExoPlayer的github地址:https://github.com/google/ExoPlayer

我最初的選擇方案更是傾向於ijkplayer,對國內開源專案本來就有一種特別的情感,國貨當自強,和朋友討論的時候,幾個朋友也是推薦我ijkplayer,這其中也有B站的哥們,但他沒參與到這個開源專案中,在最初跑demo的時候,確實可以完美播放m3u8,當我把他放到我們專案中去的時候,發現報錯了,再次檢查下匯入的包,如下:

dependencies {
# required, enough for most devices.
compile 'tv.danmaku.ijk.media:ijkplayer-java:0.8.3'
compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.3'

# Other ABIs: optional
compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.3'
compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.3'
compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.3'
compile 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.3'

# ExoPlayer as IMediaPlayer: optional, experimental
compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.3'
}

發現匯入的包沒問題,開啟原始碼看了下,是包的內部有衝突了,如下:

defaultConfig {
    minSdkVersion 21
    targetSdkVersion rootProject.ext.targetSdkVersion
    } 

最低支援21的版本,和專案有衝突,解決方案有三種,不匯入64位的包,或者自己修改原始碼後重新編譯,最後一種不現實,就是改公司專案的最低版本,我們目前還是有一部分Android 4.3的使用者。

一定會有更好的方案,嗯,一定會有的,抱著試試看的態度,無意間發現了ExoPlayer。

通過一番查閱資料,在ExoPlayer的開發者文件中可看到

ExoPlayer’s standard audio and video components rely on Android’s MediaCodec API, which was released in Android 4.1 (API level 16). Hence they do not work on earlier versions of Android. Widevine common encryption is available on Android 4.4 (API level 19) and higher.

最低支援的版本是Android 4.1,公司目前專案,最低支援是Android 4.2,挺符合我們的口味。

總結:相容性一直是一個很繁瑣的問題,版本更新太快,技術不斷更新換代,一些不安全或者沒必要的方法,不斷的從API中刪去,接著迎來了一些新加入的API,合理的考察和調研,可以省去很多彎路。

這裡寫圖片描述

健全性

對於健全性,主要體現在文件的健全性和資料的健全性,如果是一個全新的技術,官方沒有提供健全的API,市面上還沒有一些整合文件,這類的開源專案,最好別介入到專案中,作為第一個嘗試吃蜘蛛的人,可以吃到的是一嘴的苦水。

最初我在測試ijkplayer的時候,首先,簡單瀏覽了下內容,知道了個大概採用什麼技術,接著就去找文件,天哪,我只看到了整合時候需要匯入的包和編譯採用的環境、工具,還有,就是我只找到了simple。這就尷尬了,這麼大而優秀的專案,居然沒有官方文件,瞬間好感下降到了負一層,去網上搜了下資料,資料還是很健全的,有很多優秀的開發者在整合後,把一些必要的註釋就加上去了,看起來一目瞭然。

後來在調研Google的ExoPlayer的時候,發現有了質的差距,如下:

ExoPlayer 原始碼地址:

https://github.com/google/ExoPlayer

ExoPlayer api地址:

http://google.github.io/ExoPlayer/doc/reference/

ExoPlayer 開發者指南:

https://google.github.io/ExoPlayer/guide.html

這真的太棒了,整合的時候,可以解決少走很多彎路,遇到問題,也有了一些解決方案,擴充套件的時候,也為自己增加了幾分信心。

想起了中學時候學校的一句標語:“細節決定成敗,態度決定高度”。在平時使用或者學習第三方開源專案的時候,實現功能並不是第一要素,更應該關注API和資料的健全性,這點,我一直很欣賞Google和square,Google先不提,在學習square的retrofit的時候,API還是給了我很大的幫助,裡面寫的確實挺詳細,一目瞭然,每個註解都有詳細的說明,讓學習者感到更加親切。

實現原理

對於實現原理,一些初、中級開發者並不關注這個話題,總覺得自己看不懂原始碼,看不懂那些所謂的高深技術,這個就是一個錯誤的態度,原始碼看不懂也很正常,諸如ijkplayer通過封裝、修改和擴充套件FFmpeg去實現,FFmpeg,這個確實比較高深,雖然學過一段時間C語言,搞過一段時間FFmpeg,但對於內部一些程式碼,看的同樣很吃力,但文件總可以看得懂的,再或者網上那麼多資料,總可以瞭解個大概,至少可以知道ijkplayer支援的格式、採用的技術、解碼的方式、需要的包…

之前一個前輩給我的忠告,如果一項技術,一個團隊沒人很熟悉,沒人閱讀和了解過原始碼,最好不要使用,一旦使用了,以後很可能會帶來一大堆繁瑣的問題。

確實是這樣子的,就像三年多前在一家外包公司的時候,那時候市面上還沒有太多關於即時聊天的文件,當時的第三方也沒那麼多選擇,公司決定使用xmpp + openfire去實現,而那時候我們團隊沒人接觸過這一塊內容,專案在爬行中推動,一個加好友的功能,把一個同事搞了好幾天(這不否認那位同事的能力和粗心,因為英語的問題,沒去看官方文件,同時也沒過多的做調研)。

我很欣賞曹操,很欣賞他的疑人不用,用人不疑。如果曹操是一個程式設計師,一定是一位很優秀的程式碼家,以曹操的性格,一定會把一門技術吃透,然後再學以致用,舉一反三,儘可能把一門技術發揮到極致。

效能

不管採用什麼樣的開源專案,效能絕對是一個很重要的參考,就算這個專案寫得再好,功能齊全,一旦效能有問題,這將是致命一擊,就像一個失去雙手的運動員,長、短跑都是第一,此時讓他去參加乒乓球比賽,再牛逼的教練也是一臉懵逼。

回到剛才的話題,再ExoPlayer和ijkplayer中的選擇,一大部分原因是因為效能方面的問題,效能問題,直接把矛頭指向了硬解碼和軟解碼的區別。

硬解碼:就是呼叫GPU的專門模組進行解碼,由顯示卡核心GPU來對視訊進行解碼工作。

軟解碼:通過軟體讓CPU來對視訊進行解碼處理。
相信對於軟解碼和硬解碼,大部分人都不陌生,這裡不做多與贅述。

一圖勝千言,做了一下對比:

對比

上面對比中一個是功耗一個是總功耗,這個也很容易理解,GPU的電路更復雜,並行運算能力要遠遠高於CPU,於是耗電量就更高,GPU功耗大,但執行速度提升更多,功耗 = 功率 * 時間,所以就算功率乘個4,但是時間除以個10,總耗能還是降低。

對於硬解碼和軟解碼的選擇,這個真心說不上哪個更好,根據專案的需要,現在幾乎所有的裝置都支援硬解碼和軟解碼,僅支援一種的Android移動裝置已經屬於古董級的,我是沒見到過,之前更多的人願意選擇軟解碼,更大的原因是因為硬體解碼支援的格式較少,而軟解碼對於格式是不受限制的。

現在隨著硬體的不斷提高,解碼技術的不斷成熟和完善,我是更傾向硬解碼,但硬體提升的同時,CPU也在不斷的優化和提高,現在也不需要像之前那樣儘可能節省CPU,現在處於效能過剩的時代,CPU已經很難處於負荷狀態,選擇軟解碼或者硬解碼都是沒有誰對誰錯,剛剛圖上已經貼出和標記兩者的優點,根據專案需要選擇。

當時選擇硬解碼的ExoPlayer,是因為只需要播放m3u8格式的視訊,畫面上沒有那麼高的追求,對於這樣的需求,硬解碼更符合公司的口味和使用者的體驗,至少可以節省更多的電量。

功能與擴充套件

對於產品經常改需求,這是常有的事,我們更多的時間不應該是放在和產品經理撕逼,而是如何更好的應對這個問題。

剛學軟體開發的時候,書上就提到,好的程式設計師,會更好的考慮程式碼的可維護性、可重用性、可擴充套件性和靈活性。

再接入一個第三方之前,熟悉它的功能是在所難免的事,就是因為某個和某幾個功能吸引才導致我們採用這個第三方,為了方便以後擴充套件,還是應該多讀幾遍開發者文件,儘可能多的瞭解和熟悉內部結構,在開發者文件,一般都會有詳細的說明。

對於擴充套件性,這個就離不開文件和原始碼了,總不能自己莫名其妙的寫程式碼,這不現實,我覺得每個合格的程式設計師都應該養成閱讀原始碼的好習慣,這對自身的提高和功能的擴充套件都有很大的幫助。

整合性

對於整合性,我第一反應就是想到了微信和支付寶支付,這簡直就是天壤之別,兩年前的時候,我和一個同事分別接入支付寶和微信支付,我接入支付寶,加上閱讀文件和跑demo,不到一個小時就跑通了,而他接入微信支付的時候,接了一天還沒搞定,然後和我說微信支付的各種坑,當時也是半信半疑,就算坑了點,也不至於需要一天多吧,就這麼點內容。後來有一次接了個私活,也是需要接入支付寶和微信支付,支付寶的文件很全很詳細,微信的文件亂七八糟,更噁心的是回撥的類還必須是一個固定包下面的固定類名,嚴重破壞了專案的包結構,深深的鄙視。

對於開放的SDK,我覺得應該給接入者提供更加全面的文件,站在別的位置考慮下問題。

這裡寫圖片描述

總結

如何更加安全、高效地利用第三方開源專案,為了提高以後程式碼的可維護性和可擴充套件性,我們應該更多的去調研和閱讀開發者文件,磨刀不誤砍柴工,一個好的開發者,應該把更多的時間放在思考和調研,而不是速度完成需求,然後把更多的時間放在改bug。

友情推薦:

這裡寫圖片描述