關於兼容性的討論

兼容性

向後兼容和向前兼容

我們常常會見到關於向後/向前兼容性的描述,但是討論兼容性的時候一定要明確誰是兼容性的主體,是說系統兼容性還是應用軟件的兼容性,大部分時候討論兼容性都是以系統爲主體的,但是爲了避免理解歧義也要對應用軟件的兼容性有定義。這裏的 要理解成前進後退,而不是從前和以後。

  • 向後兼容性(Backwards compatibility)
    向後兼容,又名向下兼容、回溯兼容。顧名思義是向過去兼容,是新系統兼容過去的軟件(注意當針對軟件討論時是新軟件兼容過去的系統)。爲了維持原有的應用生態,大部分系統現在更新時都能夠做到向後兼容,也比較容易做到,例如最新版的Windows10仍可以運行面向Windows7的x86應用程序。
  • 向前兼容性(Forward compatibility)
    向前兼容,又名向上兼容、前瞻兼容。顧名思義是向未來兼容,是舊系統兼容未來的軟件(注意當針對軟件討論時是舊軟件兼容未來的系統)。系統的向前兼容一般都是受約束的和有限的,當系統發行方聲稱停止對某系統版本的支持時,一般即表明該版本的系統已無法做到向前兼容,也表明系統發行方推出的針對最新系統版本的程序開發套件中已將對該舊版本的兼容考慮排除在外,針對最新版本系統構建的應用程序可能無法在舊版系統中正常運行。例如Android5.0仍可以運行面向Android10.0的大部分應用程序,而已停止支持的Android4.0可能無法運行最新構建的Android應用。
兼容性相關的Version設置

(下面介紹主要以Android平臺爲例,但是處理方式在各種平臺的app開發中是基本一致的)

  • targetsdkversion:Android應用的targetsdkversion是給相對新版Android系統實現向後兼容性的依據。理論上只要新版操作系統中的api保證和舊版api行爲一致,如果需要變更行爲推出新api即可,這樣根本不需要什麼targetsdkversion,因爲任何sdkversion同名api的行爲都是一致的。但是這畢竟是理想情況,實際情況是有時候對於新的行爲會直接修改同名api的內容,但是其內部會保留之前sdk版本的行爲,當判斷目標應用程序的targetversion匹配之前的sdk版本時,api會保持對應sdk版本的行爲。所以targetsdkversion是真正 影響應用外觀和行爲 的version,也就是高於targetsdkversion的Android系統會在源碼中保證其系統的api行爲和targetsdkversion時的系統一致,但是低於targetsdkversion的Android系統的api表現卻只能和當前系統一致了。
  • minsdkversion:minsdkversion是應用程序正常運行被動需要(或者說主觀承諾)的最低版本,它包含了應用正常運行的 必需Api集合,應用商店會據此判斷低於minsdkversion的設備將無法安裝該應用。開發階段要注意調用任何超過minsdkversion版本以上的api時都必須判斷當前系統的版本是否低於該api需要的版本,並在低於時使用替代方案(禁用或使用閹割版的功能和體驗),直接調用的話可能會在較低版本的設備上閃退。當應用的核心功能需要調用過多新版本api以至於無法(或開發者認爲性價比很低而不值得)爲低版本安卓實現替代方案時,此時認爲當前應用場景無法支持該版本的安卓系統應當放棄兼容。另外需要注意minsdkversion不僅需要適配不存在的api,也需要注意適配行爲和targetsdkversion不一致的api,需要在不一致時在源碼中進行判斷並處理。也就是targetsdkversion設置的很高也不是沒有壞處,這會造成targetsdkversion以上的設備和minsdkversion的api行爲差異過大,無形中增加適配成本。
  • compilesdkversion: compilesdkversion是Android編譯和build使用的版本,它決定了應用 可調用的Api集合,這是Android比較特殊的一個版本設置(UWP和iOS開發均只提供了min和target版本兩個選項,編譯時默認使用target版本的sdk),而android編譯的sdk版本和target版本是不一致的。 compilesdkversion不會被編譯到apk中,也就不會改變apk的運行時的行爲,僅僅是爲IDE提供編譯警告和錯誤的依據,一般都是設置爲最新版。額外設置一個compilesdkversion的一個作用是警示不要調用過時或將要廢棄的api便於日後維護(儘管在發佈targetsdkversion時該api並沒過時);另一個作用是可以在較新版本的系統中調用高於targetsdkversion的新api,但我覺得儘量不要這麼做,因爲其它所有api的行爲都是targetsdkversion時的,只有新api的行爲是新的,可能會由於行爲的版本不一致而造成一些問題,這也是UWP和iOS沒有設置compilesdkversion的考慮原因之一。
  • 理論上幾個版本的關係是earliestversion<=minsdkversion<=targetsdkversion<=compilesdkversion<=lattestversion,其中earliestversion是當前仍然支持的最早版本,lattestversion是當前推出的最新版本,總體來說就是用較低的minSdkVersion來覆蓋最大的人羣,用最新的compileSdkVersion和較新的targetsdkversion來獲得最好的外觀和行爲。而我覺得是這樣來決定版本:minsdkVersion應當包含實現該應用核心功能必不可少的api,targetsdkversion應當包含實現該應用所有預期完整功能的api且和minsdkversion的行爲差異不至於過大,如果有compliesdkversion設置則直接無腦設置成當前最高sdk版本。
Android Support Library

Android Support Library兼容包 提供 了舊版Android系統對新開發的Android應用的向前兼容性,而且這種兼容性不僅僅是能夠運行,還能使用部分(注意不是全部)新版本的api和feature。本身這些library應當是作爲安卓操作系統更新集成在系統裏給用戶的,但是有些用戶不更新或硬件無法支持更新操作系統,所以纔有了這種擴展庫的形式。要注意v4、v7等library是有對應sdk版本的,也就是它們會隨着Android系統的更新而不斷更新,他們對應的sdk版本即擴展庫所支持的最高版本的api,所以程序添加兼容包依賴可以大大提高應用程序的兼容性。隨着Android系統不斷更新,在API Level 24的時候移除了Android2.3(API level 9)以下版本的支持,在API Level 26的時候移除了Android4.0(API level 14)以下版本的支持,所以目前最新的兼容包最低只支持到Api level 14了,也就是目前的新項目設置minsdkversion至少爲14,當然如果你的項目minsdkversion仍希望支持更早的Android設備(儘管這不被推薦),可以使用舊版本的Supprot Library,然後將minsdkversion設置爲9甚至是4。

  • android-support-v4:該庫最初支持的最低版本是Api Level 4的庫,所以稱其爲V4。它包含了Fragment,NotificationCompat, LoadBroadcastManager, ViewPager,PageTabAtrip,Loader,FileProvider等庫和控件
  • android-support-v7:該庫最初支持的最低版本是API Level 7的庫,所以稱其爲V7。v7兼容包依賴於v4包並額外提供了一些api,是v4的超集,額外功能包括新的Theme,value,佈局,新的控件,新的動畫實現方式等等
  • Androidx: 從android9.0(API Level 28)開始,android的support庫進行了更新,未來新的特性和改進都會進入Androidx包來取代v4和v7兼容包,v4和v7的版本的support庫都停留在了28版本。因爲support庫的命名令人迷惑並且包越來越臃腫(歷史包袱沉重), Androidx包括目前v4和v7的所有內容但是部分命名空間有所改,如果你的項目引入的部分三方庫依賴v4或v7則只能繼續使用v4和v7,如果沒有的話則應當只使用Androidx
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章