自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

滴滴國際化項目 Android 端演進

開發(fā) 開發(fā)工具
目前,大家用滴滴 App 在美國是可以打車的,那今天我們就來講一下滴滴國際化項目 Android 端的演進。

目前大家用滴滴 App 在美國是可以打車的,對的,不用下載新的 App,現(xiàn)在的滴滴 App 在美國打開就會自動顯示海外打車頁面。

國際化在技術(shù)上有一定的特殊性,主要包括:

滴滴 App 在美國打開的頁面

(1) 地圖

地圖作為滴滴客戶端重要的支持及基礎,而目前我們的友商都沒有海外的路網(wǎng)數(shù)據(jù),國際化我們需要接入新的國外地圖提供商。

(2) 對接不同的運力

目前滴滴國際化是與海外投資的伙伴進行合作,比如美國打車跟 Lyft 合作。

(3) 漫游網(wǎng)絡

目前國際化的主要用戶場景還是國內(nèi)用戶出國打車,這時用戶是用國內(nèi)手機和運營商海外漫游接入網(wǎng)絡。

以上的三個特殊性決定著我們需要在技術(shù)上的差異,下面的分享也圍繞地圖模塊、漫游網(wǎng)絡、多業(yè)務接入項目演進進行分享。

1. 地圖

這塊主要包括兩大問題:(1) 地圖選型,(2) 地圖切換

1.1 地圖選型

滴滴是個重度依賴地圖的 App,而目前我們的友商及大部分國內(nèi)地圖提供商都沒有海外的路網(wǎng)數(shù)據(jù)。

我們前期針對的場景是國內(nèi)用戶海外打車,Google Map 依賴 Google Play Service,國內(nèi)手機幾乎都沒有這個 Service,即便安裝了 Google Play Service 部分手機也無法運行,另外即便都有了,漫游網(wǎng)絡也不能訪問 Google Map,所以最靠譜的 Google Map 一開始便被排除。

另外國內(nèi)有些 App 在海外用了 Google Map,不過是通過中轉(zhuǎn)下發(fā)地圖切片的方式完成的,我們對地圖各方面的要求都很高,所以也不合適。

這些都要求我們?nèi)フ乙粋€合適的國外地圖。

(1) 海外地圖選型考察點

海外地圖選型考察點

我們對地圖強依賴,有些定制需求,如:很多 Marker 并且添加后需要修改、畫圓并可以動態(tài)調(diào)整半徑等等

國外可用地圖數(shù)據(jù)源主要有 OpenStreetMap、Here、Tomtom,OpenStreetMap 是個開源的地圖數(shù)據(jù)源,類似維基百科的模式,所以數(shù)據(jù)很全很新,甚至超過 Google Map,但不可避免會有些臟數(shù)據(jù),前期的話我們主要是針對大城市,OpenStreetMap 的數(shù)據(jù)可以滿足我們的需求。

因為涉及到異地跨時區(qū)溝通,所以我們希望技術(shù)支持力度夠大。

性能包括地圖啟動時間、渲染速度、前端響應速度、后端響應速度。

在開始國際化前,當時滴滴的安裝包就已經(jīng)很大了,基本是國內(nèi)主流 App 之首(當然現(xiàn)在滴滴 App 已經(jīng)挺小了),所以我們希望新的地圖夠小。

(2) 海外地圖全面對比

Mapbox、Nutiteq、Here、Tomtom、Bing 共五款海外地圖全面對比

這次我們調(diào)研了 Mapbox、Nutiteq、Here、Tomtom、Bing 共五款海外地圖。其中

Bing 沒有 Android 版;

Tomtom 有很古老的 Android 版,但功能過于簡單,文檔又幾乎沒有;

Here SDK 高達 40M,與他們溝通后,精簡也只能到 25M,這個大小對我們是絕對接受不了的;

所以我們重點集成和測試的是 Mapbox 和 Nutiteq 這兩家地圖供應商。

Mapbox 和 Nutiteq 的功能和性能都滿足我們需求,地圖數(shù)據(jù)源也都是以 OSM(OpenStreetMap) 為主。

Mapbox 的 API 設計和國內(nèi)地圖類似,都是向 Google Map 靠攏,所以上手簡單,并且整個 SDK 都是開源的,地圖的樣式也更美觀些,而 Nutiteq 的地圖底層設計比較獨特,API 用法很不尋常,這也給我們接入帶來了很大的麻煩。

Mapbox 有眾多的 Web 用戶,包括訪問量都不低的 Foursquare、Pinterest 等,但 Android 端用戶并不多;Nutiteq 的 Android 用戶多些,但整體量也不是很大,不過我們并沒有更好的選擇,而且前期我們的量也不會很大,所以他們都在可接受范圍內(nèi)。

綜合下來看的話,我們是更傾向于 Mapbox,不過 Mapbox 只能通過 GitHub Issues 和郵件反饋問題,反應很慢;Nutiteq 可以 Skype 溝通,效率很高。為了保險起見,Mapbox 和 Nutiteq 都做了全面接入和測試,最終證明這樣是有用的。

跟多數(shù) App 一樣,為了使得包更小,我們的主工程配置了 abiFilter “armeabi”,僅打 armabi 的 so,而 Mapbox 的 armeabi so 無法跑在 armv7 機器上,前期集成測試我們通過修改 Gradle 腳本在編譯時 copy so 的方式讓測試通過,而 Mapbox 一直不愿意改,國內(nèi)市場又不支持 Google 的 Apk Splits 機制,所以最終放棄 Mapbox 而選擇 Nutiteq。

后話:Mapbox ***版已經(jīng)解決了這個問題,而且國內(nèi)有相關(guān)的市場人員,溝通起來也順暢多了。

1.2 地圖切換

用不了 Google Map 帶來一個要求,我們選擇的地圖必須支持多國家,并且在設計時要支持以后不同地圖任意切換。是的,即地圖和 App 弱依賴。針對這個問題我們設計了地圖隔離層。

總體設計如下:

地圖隔離層總體設計

上圖第二層 MapSDK 是地圖的標準 API 層,App 只與此層打交道,標準層的 API 設計以 Google Map API 為標準。

第三層 Adapter 層是具體地圖到標準 API 的適配實現(xiàn)層。每個地圖都有個 Adapter,負責將地圖 API 轉(zhuǎn)換成標準 API。

將原來的 App 與三方地圖直接依賴改為 App 依賴表示標準 API 的 MapSDK 層,由 MapSDK 通過具體的 Adapter 調(diào)用三方 SDK,這樣地圖切換只需要替換依賴的 Adapter 即可,其他地方無需改動。

新的設計后編譯依賴關(guān)系如下:

新的設計后編譯依賴關(guān)系

App 依賴 Map Adapter,Map Adapter 依賴我們的 MapSDK 和三方的 Map SDK。

當我們需要更換三方地圖 SDK 時,僅需更換對應的 Map Adapter 即可。對于 Android,build.gradle 中更換依賴即可。

1.3 新的地圖模塊設計的好處

(1) 解耦,切換成本低

這個上面已經(jīng)介紹,再也不會因為換了地圖牽一發(fā)而動全身。

(2) 學習成本低

業(yè)務開發(fā)人員只需要熟悉標準 MapSDK API 即可,不用了解其他地圖的具體使用,時間成本降低。

(3) 通用

適用于所有 App,以后新增 App,可直接使用之前成型的 Adapter。

1.4 地圖切換實現(xiàn)的注意事項

(1) 所有 API 適配

理論上 MapSDK 應為地圖所有 API ***集,實際可以根據(jù)情況先去做所需功能的定義和適配。

(2) 標尺

需要統(tǒng)一標尺,如縮放尺度、相同坐標系等。

(3) 未支持 API 處理

因為標準層的 MapSDK 是地圖功能***集,所以不可避免某些三方地圖不支持 MapSDK 定義的功能。比如根據(jù)一組點縮放這個功能,其對應的 Adapter 在實現(xiàn)這個功能時如果是 Debug 模式則拋異常,Release 模式則空實現(xiàn)。

還有如 MapSDK 的 API 規(guī)范前面已經(jīng)介紹過以 Google Map API 為標準。另 Adapter 有具體的開發(fā)規(guī)范要求。

2. 漫游網(wǎng)絡

前面介紹過我們初期針對的是國內(nèi)用戶海外打車場景,這時用戶是用國內(nèi)手機和運營商海外漫游接入網(wǎng)絡,所以需要針對網(wǎng)絡訪問進行優(yōu)化。

一般漫游網(wǎng)絡流程如下圖:

海外漫游網(wǎng)絡訪問流程圖

用戶由海外運營商接入國內(nèi)運營商,再通過公網(wǎng)(有墻)訪問 Web。我們的服務器部署在 AWS 上,用戶海外漫游打車網(wǎng)絡流程如下圖:

用戶海外漫游網(wǎng)絡打車訪問流程圖

由于公網(wǎng)訪問 AWS 非常慢,我們添加了海外專線,優(yōu)化后用戶海外漫游打車網(wǎng)絡流程如下圖:

用戶海外漫游網(wǎng)絡打車訪問優(yōu)化后流程圖

用戶先訪問到國內(nèi)的中轉(zhuǎn)服務器,中轉(zhuǎn)服務器再通過海外專線訪問 AWS。

這個過程中客戶端要做的工作包括:

(1) 拉取中轉(zhuǎn)服務器域名列表

(2) 使用中轉(zhuǎn)服務器域名列表中域名訪問,出錯則用原始域名降級重試

(3) 定時及推送更新域名列表

這里域名順序由服務端自己負載均衡,返回的中轉(zhuǎn)服務器域名列表是中轉(zhuǎn)服務器域名還是直接海外域名也由服務器決定。

3. Android 項目演進

3.1 原有模式

之前國際化業(yè)務的工程是很簡單的方式,所有業(yè)務、組件、工具放在一起,根據(jù)具體包名劃分:

國際化業(yè)務的工程

這個在早期問題不大,并且開發(fā)起來快速方便,但隨著更多業(yè)務接入,如我們前面說過的新的國家運力接入,問題就日益明顯,包括:

(1) 組件之間耦合

雖然已經(jīng)劃分包名,但依然可以互相調(diào)用,組件間依賴關(guān)系不清,甚至有循環(huán)依賴。

(2) 添加新業(yè)務不便

(3) 開發(fā)問題

規(guī)模越來越大致提交沖突可能性變大。

3.2 SDK 工程提取

將原工程整體拆分為業(yè)務工程和 SDK 工程,單業(yè)務工程直接依賴 SDK,可獨立開發(fā)、獨立運行、獨立打包。如下:

Android 項目抽離 SDK 工程設計

這樣在接入新的業(yè)務后,總體項目結(jié)構(gòu)如下圖:

 SDK 工程總體項目結(jié)構(gòu)

每個業(yè)務作為單獨工程,共用組件、工具、業(yè)務統(tǒng)一到 SDK 層中。

集成工程負責集成 Lyft、Ola、GrabTaxi 項目,所有業(yè)務項目提供 AAR,由集成工程整體打包對外發(fā)布。

3.3 SDK 工程組件化拆分

為了解決組件之間耦合,防止后續(xù)問題加劇,同時方便協(xié)同開發(fā)和更好的復用,將 SDK 工程組件化拆分如下:

將 SDK 工程組件化拆分

SDK 整體拆分為 Business Library 和 Util Library 兩大部分,主要依據(jù)是是否可以獨立于我們業(yè)務,他們間不允許反向依賴。每個部分包含若干組件,每個組件都以 Module 形式存在。

Business Library 為通用業(yè)務層,包含通用業(yè)務組件,如平滑移動、上車點、定位、地理信息、打點、網(wǎng)絡封裝。

其中 CommonBusiness 存放暫時通用、但尚不足以作為一個單獨組件的公共業(yè)務,以后可能獨立出來,注意包名規(guī)范方便未來獨立。

Util Library 為工具庫,大致分為 View 和 Util,DidiSDK 為滴滴 App 整體通用組件包,包含通用的圖片緩存、網(wǎng)絡請求、基礎登陸組件等等。

3.4 SDK 組件化拆分后依賴關(guān)系圖

SDK 組件化拆分后依賴關(guān)系圖

通過上圖我們可以發(fā)現(xiàn)即便只是 Business Library 層,組件也根據(jù)依賴關(guān)系劃分為明顯的上下層。

3.5 SDK 組件化劃分事項

(1) 單一及開閉原則

每個模塊只代表一個功能模塊或一個公共業(yè)務,對于個性化或定制功能以接口形式對外開放。

PS:目前 CommonBusiness 模塊暫時作為國際化 SDK 整體集成打包的模塊,即國際化 SDK 項目中的 sdk Module,后續(xù)當其中某個公共業(yè)務足夠成為一個模塊時可繼續(xù)拆分出來。

(2) 拆分粒度

項目的演進是不斷進行的,沒必要將每個細小組件都拆分出來,這樣不僅增加了項目的復雜度,同時也會影響編譯時間。

先根據(jù)實際需要拆分必要的組件,太小暫不足以獨立的組件可以在以后不斷進行的重構(gòu)中根據(jù)需要拆分。如上面的 CommonBusiness 模塊,當然需要保持一定的規(guī)范方便以后拆分。

(3) 依賴關(guān)系

通過依賴圖整理依賴關(guān)系,防止重復依賴,同時看出沉淀關(guān)系。

1. Util Library 不能反向依賴 Business Library;

2. Business Library 除了基礎部分,如 Net、Geo、EventTrack 外,其他部分盡量不要相互依賴;

3. Business Library 中 Net、Geo、EventTrack 不允許反向依賴其他模塊。

(4) 開發(fā)規(guī)范

為了保證擴展性及方便以后繼續(xù)拆分:

  • 所有業(yè)務包名以 com.didi.{xx}.sdk.{businessName} 開頭;
  • CommonUtil 模塊中所有工具包名以 com.didi.{xx}.sdk.util.{utilName} 開頭;
  • CommonView 模塊中所有 View 包名以 com.didi.{xx}.sdk.view.{viewName} 開頭;

(5) 組件間通信

放棄原來造成耦合嚴重的EventBus,改用原生的通信方式,包括原生 (startActivityForResult) 、內(nèi)部廣播、回調(diào)等。

3.6 SDK 組件化項目整體設計圖

SDK 組件化項目整體設計圖

其中虛線部分為 SDK 層。

3.7 組件化拆分后的好處

(1) 組件間解耦

(2) 業(yè)務并行開發(fā)、測試

(3) 組件單獨測試

【本文是51CTO專欄作者Trinea的原創(chuàng)文章,轉(zhuǎn)載聯(lián)系作者本人獲取授權(quán)】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2024-04-02 07:56:41

2011-07-08 11:13:42

Cocoa Touch XCode

2018-05-24 15:19:19

AWS創(chuàng)業(yè)云服務

2023-04-07 15:12:46

ReactReact-Intl

2021-05-17 10:13:24

iOS名詞復數(shù)開發(fā)

2009-06-25 16:04:30

2010-01-04 13:09:51

Silverlight

2011-05-17 09:39:38

JavaSE

2011-08-19 13:13:14

struts2Java

2025-02-14 10:27:30

2024-09-04 10:27:53

2009-12-29 15:05:29

WPF支持國際化

2009-02-04 15:04:13

2024-01-17 10:16:22

前端國際化消息鍵

2010-03-02 16:44:59

CentOS Mono

2010-07-28 14:52:29

Flex國際化

2024-05-17 08:25:06

數(shù)據(jù)驅(qū)動React語言包

2011-08-29 09:48:30

springMVC

2022-07-27 10:39:14

Spring代碼IDEA

2023-01-31 10:29:26

JavaScript國際化國際化庫
點贊
收藏

51CTO技術(shù)棧公眾號