1. 程式人生 > >一個常用專案的演進,重構和版本更新的歷程

一個常用專案的演進,重構和版本更新的歷程

一個專案的版本更新的過程總是伴隨著技術的演進和程式碼的重構,只要你在維護你總是會發現有更好的或者說是更合適的控制元件,框架值得去適用,這個過程可以是幾個星期或者是幾個月。
在這裡我試著去分析一下通用專案更新跌代的維護歷程。

常見的UI控制元件演進:
1. 跟隨流行風尚將普通主頁改為側滑主頁,玩起來更炫更簡單有趣;
2. 用RecyclerView代替ListView,因為RecyclerView具有更強的擴充套件性,靈活性,以後的不管什麼資料展示,瀑布流什麼之類,寶寶再也不用大刀闊斧的進行程式碼重構了。

網路框架的演進:
在最開始決定使用那種網路框架的時候我們做了個貨比三家不吃虧,下面我就來對比一下這些常用網路框架的特點和優缺點吧

在看android基礎的時候,關於網路操作一般都會介紹HttpClient以及HttpConnection這兩個包。前者是apache的開源庫,後者是android自帶的api。既然提到了他們,都二者進行一個比較,谷歌在官方文件已經說明了,建議在2.3以及以上版本使用 HttpConnection。具體原因呢,是因為對2.1和2.2版本,HttpURLConnection有那麼幾個Bug,所以建議用Apache 的HTTP Client;之後的版本,建議用HttpURLConnection。Apache的HTTP Client比較強大,擁有龐大而靈活的API,這個實現很穩定,並且Bug很少。然而,也就是因為太龐大了,以至於很難在保證相容性的情況下改進它,故 android 開發團隊不應該維護該庫而是轉投更為輕量級的httpurlconnection。
當我們開發企業級應用的時候,一般都會選擇使用已經封裝好的http框架。開源的比較流行的有:
volley


特色 :
Google推出了官方的針對Android平臺上的網路通訊庫volley,能使網路通訊更快,更簡單,更健壯,Volley在提供了高效能網路通訊功能的同時,對網路圖片載入也提供了良好的支援,完全可以滿足簡單REST客戶端的需求, 我們沒有理由不跟上時代的潮流。另外,但volley的擴充套件性很強,可以根據需要定製你自己的網路請求。所以,最後推薦還是使用volley進行開發,當然其他幾個庫也是非常具有學習以及參考意義的,可以將他們的精髓之處汲取到volley框架的拓展開發之中,做出自己理想的http通訊框架。
簡單來說,它提供瞭如下的便利功能:
JSON,影象等的非同步下載;
網路請求的排序(scheduling)
網路請求的優先順序處理
快取
多級別取消請求
和Activity和生命週期的聯動(Activity結束時同時取消所有網路請求)
底層的網路請求程式碼更加清晰,在Volley返回的結果即直接返回了我們需要的Object,同時將統一的錯誤處理、公共的引數處理和一些公共的返回使用的引數,全部放在我們自定義的Request當中,這樣外部請求所需要傳入的引數更少,對於錯誤的處理更加簡單,只需要考慮業務需要的Response,其他全域性的返回內容則無需進行干擾。通過Volley的引入,幫助我們在業務的開發上變得更加便捷。

缺點:比如大資料(large payloads ),流媒體,這些case,還需要使用原始的方法,比如Download Manager等。

2、OkHttp優點較多
OkHttp是一個現代,快速,高效的Http client,支援HTTP/2以及SPDY,一種開放的網路傳輸協議,由Google開發,它為你做了很多的事情。

OKHttp是Android版Http客戶端。非常高效,支援SPDY、連線池、GZIP和HTTP快取。

支援SPDY,可以合併多個到同一個主機的請求

OkHttp實現的諸多技術如:連線池,gziping,快取等就知道網路相關的操作是多麼複雜了。

OkHttp扮演著傳輸層的角色。

OkHttp使用Okio來大大簡化資料的訪問與儲存,Okio是一個增強 java.io 和 java.nio的庫。

OkHttp 處理了很多網路疑難雜症:會從很多常用的連線問題中自動恢復。如果您的伺服器配置了多個IP地址,當第一個IP連線失敗的時候,OkHttp會自動嘗試下一個IP。

OkHttp還處理了代理伺服器問題和SSL握手失敗問題。

OkHttp是一個Java的HTTP+SPDY客戶端開發包,同時也支援Android。需要Android 2.3以上

OKHttp是Android版Http客戶端。非常高效,支援SPDY、連線池、GZIP和 HTTP 快取。

預設情況下,OKHttp會自動處理常見的網路問題,像二次連線、SSL的握手問題。

如果你的應用程式中集成了OKHttp,Retrofit預設會使用OKHttp處理其他網路層請求。

從Android4.4開始HttpURLConnection的底層實現採用的是okHttp

快取響應避免重複的網路請求

目前,該封裝庫志支援:

1, 一般的get請求

2,一般的post請求

3,基於Http的檔案上傳

4, 檔案下載

5,上傳下載的進度回撥

6, 載入圖片

7, 支援請求回撥,直接返回物件、物件集合

8, 支援session的保持

9, 支援自簽名網站https的訪問,提供方法設定下證書就行

10, 支援取消某個請求

為什麼要做快取,或者說有什麼好處?

減少伺服器負荷,降低延遲提升使用者體驗。

複雜的快取策略會根據使用者當前的網路情況採取不同的快取策略,比如在2g網路很差的情況下,提高快取使用的時間;不用的應用、業務需求、介面所需要的快取策略也會不一樣,有的要保證資料的實時性,所以不能有快取,有的你可以快取5分鐘,等等。你要根據具體情況所需資料的時效性情況給出不同的方案。當然你也可以全部都一樣的快取策略,看你自己。

3. xUtils簡介

xUtils 最初源於Afinal框架,進行了大量重構,使得xUtils支援大檔案上傳,更全面的http請求協議支援(10種謂詞),擁有更加靈活的ORM,更多的事件註解支援且不受混淆影響…
xUitls最低相容android 2.2 (api level 8)

目前xUtils主要有四大模組:
DbUtils模組:
android中的orm框架,一行程式碼就可以進行增刪改查;
支援事務,預設關閉;
可通過註解自定義表名,列名,外來鍵,唯一性約束,NOT NULL約束,CHECK約束等(需要混淆的時候請註解表名和列名);
支援繫結外來鍵,儲存實體時外來鍵關聯實體自動儲存或更新;
自動載入外來鍵關聯實體,支援延時載入;
支援鏈式表達查詢,更直觀的查詢語義,參考下面的介紹或sample中的例子。
ViewUtils模組:
android中的ioc框架,完全註解方式就可以進行UI,資源和事件繫結;
新的事件繫結方式,使用混淆工具混淆後仍可正常工作;
目前支援常用的20種事件繫結,參見ViewCommonEventListener類和包com.lidroid.xutils.view.annotation.event。
HttpUtils模組:
支援同步,非同步方式的請求;
支援大檔案上傳,上傳大檔案不會oom;
支援GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT請求;
下載支援301/302重定向,支援設定是否根據Content-Disposition重新命名下載的檔案;
返回文字內容的請求(預設只啟用了GET請求)支援快取,可設定預設過期時間和針對當前請求的過期時間。
BitmapUtils模組:
載入bitmap的時候無需考慮bitmap載入過程中出現的oom和android容器快速滑動時候出現的圖片錯位等現象;
支援載入網路圖片和本地圖片;
記憶體管理使用lru演算法,更好的管理bitmap記憶體;
可配置執行緒載入執行緒數量,快取大小,快取路徑,載入顯示動畫等…
使用xUtils快速開發框架需要有以下許可權:

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 

混淆時注意事項:
新增Android預設混淆配置${sdk.dir}/tools/proguard/proguard-android.txt
不要混淆xUtils中的註解型別,新增混淆配置:-keep class * extends java.lang.annotation.Annotation { *; }
對使用DbUtils模組持久化的實體類不要混淆,或者註解所有表和列名稱@Table(name=”xxx”),@Id(column=”xxx”),@Column(column=”xxx”),@Foreign(column=”xxx”,foreign=”xxx”);

缺點:程式碼量大,程式碼可讀性變差,冗餘影響程式執行效率

4. Retrofit
Retrofit2.0用了動態代理技術,通過解析註解生成Http請求,把請求交給OkHttp,然後通過我們設定的ConverterFactory進行serialization和deserialization,最後通過CallAdapter把結果進行進一步適配,實現了對Rxjava,Guava和java8的支援。

retrofit使用了builder模式,我們可以在此設定請求的URL,ConverterFactory(此處用了Gson解析,當然你也可以自定義資料解析器,只要你的解析器繼承 Converter.Factory就行),或者設定回撥時的介面卡。在retrofit中提供了三種CallAdapterFactory:GuavaCallAdapterFactory,Java8CallAdapterFactory和RxJavaCallAdapterFactory。

圖片載入框架的演進

是以圖片加文字為主體的內容,因此會有大量的圖片顯示需求。和網路框架選型類似,早期選擇了比較熟悉的UIL來做圖片載入,可以同時支援本地圖片和網路圖片的載入,在當時可以滿足我們的基本需求。
我們開始使用更加高清的圖片,隨之載入速度變慢,佔用更多的記憶體,而且這個時候UIL的作者基本很少維護。我們開始調研使用新的圖片載入框架。此時Fresco剛剛出來,還不太穩定,當時沒敢用。給我們的可選項有Picasso和Glide兩個可選項,Picasso比較輕量,但是相比於UIL在效能上沒有太好的提高。Glide程式碼量較大,不過它會在本地儲存多份快取(原始圖片和實際顯示尺寸的圖片),這樣載入本地快取的時候,可以直接顯示大小剛好的尺寸,減少解碼的時間,因此會比UIL要快很多。
後來我們需要支援gif的動畫顯示,而Glide對動畫的相容性又不是特別好,這個時候我們直接切到了Fresco。同時Fresco對webp的良好支援,使得我們在後期切換到webp格式的時候,減少了很多工作量。Fresco在4.4及以下版本使用匿名記憶體來作為記憶體快取,為我們減少OOM做了巨大的貢獻。
我們使用的這幾個圖片載入框架,每個框架的使用都有非常大的區別,這就導致遷移的時候工作量巨大。為了降低遷移成本,我們封裝了自己的ImageLoader,在ImageLoader中來實現具體的圖片載入,這樣保證在遷移的時候,最大程度的降低程式碼的改動(不過在遷移到Fresco的時候還是改動巨大,因為我們不能直接使用ImageView了o(︶︿︶)o。

推送的升級
推送,我覺得也有必要說一說。最初我們快速選用了百度雲推送,在當時看來百度的推送比較穩定,同時接入比較簡單。實際使用了一年之後,發現送達率不是特別高,並且資料統計做的不太好,無法比較好的統計推送效果。在調研之後,我們決定遷移到小米推送+友盟推送的模式,針對小米使用者開啟小米推送,其他使用者採用友盟推送,為了平滑過渡,在切換期間同時向未升級的老使用者繼續使用百度雲推送進行推送。

架構升級
一般專案中由於一直以來在業務開發佔用的時間比較多,目前App的整體架構沒有做過太大的改變。
在Adapter的使用方面,我們將ListView或RecyclerView的Item放到單獨的ItemHander,這樣可以在不同的頁面可以通過將不同的Item組裝到一起,從而滿足不同地方的需求。這樣可以在ListView或RecyclerView來複用相同的程式碼,提高程式碼的可維護性。
前面網路層說到我們的錯誤處理,這個也是做過比較大的升級。最初時候,網路錯誤、http請求錯誤、後臺和客戶端的錯誤,都分別在不同的層級進行處理。目前我們在發生錯誤的時候將錯誤全部以Exception的方式丟擲,最後在上層進行錯誤的處理。
App中的狀態同步,早期使用使用資料庫快取部分資料,或者使用LocalBroadcast進行廣播通訊,前者有很多的限制,後者使用起來較為複雜。近期我們改用EventBus進行狀態同步,同時這樣也使得各個頁面之間的耦合也低。
App中佔比很大的部分是從網路請求資料,獲得資料後進行展示,還是以MVC為主。在一些模組的部分地方,做一些databinding,MVP等的測試。後面有機會會更多大範圍的重構。

APK最初大約只有5M,歷史最高峰達到了23M,在App減肥上我們也做了一些努力,主要是使用tinypng壓縮圖片,so只保留arm的支援.

現在持續整合還是蠻火的,自然我們也在用。最初的時候,我們每天需要手動打包,打完包之後開啟fir的網站,將apk傳上去,然後在公司的微信群吼一聲,告訴大家我們發包了。經歷一段時間後,我們編寫了一個Gradle外掛幫助我們自動上傳到fir,在之後我們搭建了Jenkins自動完成這一系列步驟,並通過郵件告知大家;

相關推薦

一個常用專案演進,重構版本更新歷程

一個專案的版本更新的過程總是伴隨著技術的演進和程式碼的重構,只要你在維護你總是會發現有更好的或者說是更合適的控制元件,框架值得去適用,這個過程可以是幾個星期或者是幾個月。 在這裡我試著去分析一下通用專案更新跌代的維護歷程。 常見的UI控制元件演進: 1.

iOS開發 從一個專案建立ViewControllerxib

1、新建一個Empty Application,只選Use Automatic Reference Counting,Use Core Data和Include Unit Tests不選。 2、Command+N 新建檔案,選Cocoa Touch UIViewCont

提交本地專案到github提交更新

一:首先當然是去github註冊賬號了。 二:註冊完畢登入後,在自己的首頁上面點選右上角“+”號,然後選擇New repository,或者直接點選下面的綠色按鈕,建立一個新倉庫。如圖: 然後填入倉庫的名稱: 填寫完畢後,點選下面的綠色按鈕,建立倉庫。 下載完畢

idea:專案新增SVN版本管理快捷鍵

1.開啟svn功能 選單欄》VCS》Enable Version Control Integration》下拉框選擇Subversion》點選OK 2.將專案新增到svn庫。 選中專案,

eclipes建立一個web專案web.xml不能自動更新的原因(web.xml@WebServlet的作用)

在eclipse中建立一個Web專案的時候,雖然有web.xml生成,但是再新增Servlet類檔案的時候總是看不見web.xml的更新,所以異常的鬱悶!上網查了查,原來我們在建立Web專案的時候,會彈出一個對話方塊,“Dynamic web module version”

【安全牛學習筆記】?KALI版本更新手動漏洞挖掘(SQL註入)

信息安全 security+ sql註入 漏洞 KALI版本更新-----第一個ROLLING RELEASEKali 2.0發布時聲稱將采用rolling release模式更新(但並未實施)Fixed-release 固定發布周期 使用軟件穩定的主流版本 發布--

Unity(Android版)Android原生APP簡單實現版本更新

directory 代碼 server 頁面 提示框 自動安裝 obj nis 查看 版本檢測接口說明:(1)請求post,無參數(2)調用地址:http://www.baidu.com/rs/ver/info(3)返回結果:{ "verCode": "2",

常用算法設計優化策略(本蒟蒻不定期更新

遞歸 還要 定期 兩個 順序 結構 等價 狀態 logs 常用算法設計和優化策略(本蒟蒻不定期更新) 下面是紫書上講的常用算法設計策略和優化策略: 分治法:將問題分成相同的獨立子問題求解。拆分出的問題必須有最優子結構性質(子問題求出的是最優解) 動態規劃。本質是:對於一個

版本更新相關,CFBundleVersionCFBundleShortVersionString的比較,獲取版本

移動客戶端進行版本迭代時,需要進行本地版本號和伺服器版本號比較,從而實現更新提示。本文祥講怎樣獲取版本號,具體的比較方法。 一、CFBundleShortVersionString和CFBundleVersion     &nb

8102年底如何開發維護一個npm專案

開發流程 初始化 首先在npm官網進行註冊登入 執行npm init,可以通過命令列進行一些初始化的設定,如果想快速進行設定,可以執行npm init -y,會在專案的根目錄生成一個package.json的檔案,具體包含哪些配置可以參考官方文件,下面介紹一些常用的配置。 name:npm包的名稱 v

一個簡單的酒店專案【前臺使用者後臺】以及微信對接

  這兩月我用了這麼久的時間寫的專案,無償分享給大家。首先,先申明這裡面程式碼非常多bug,還有很多功能沒有完成,緊靠一個學生實在太難了。那麼我先講講專案的bug,以及未完成的功能,避免大家找到又說壞話。還有專案有部分個人隱私,大家看到就當沒看到吧,反正我的資訊又不值幾個錢。哈哈~~~

2018年9月26日Django的安裝以及建立第一個Django專案子模組

python字串物件的find()和index()方法的區別? index()和find()函式都是用於查詢字串,但是index()在沒有找到子串的時候會有報錯丟擲異常,影響程式執行。find()在找不到目標子串時不會丟擲異常,而是會返回-1,因此不會影響程式的執行。   函式

安卓專案實戰之APP版本升級更新,適配安卓7.0

前言 APP的版本升級主要分為兩種方式: 1.應用市場升級 2.應用內升級 而應用內升級的方式是目前大多數APP採用的升級更新方式。 應用內升級的模式 按照不同的業務需求又可以分為兩種: 1,強制性更新 如果APP有更新,那麼則彈出更新提示對話方塊,並且

利用vue-cliwebpack建立一個Vue專案

建立Vue專案 步驟如下: 1、全域性安裝vue-cli      在工作空間下執行下面這段程式碼 cnpm install --global vue-cli 2、建立一個基於webpack模板的新專案 vue i

使用virtualenv建立python虛擬環境一個Django專案

python虛擬環境--virtualenv virtualenv是一個建立隔絕的Python環境的工具。virtualenv建立一個包含所有必要的可執行檔案的資料夾,用來使用Python工程所需的包. window安裝 pip install virtualenv 或 pip3

更新maven依賴時 專案默j2SE1.5版本

只需要在maven專案的pom.xml中將編譯器的版本指定為1.8即可  程式碼如下: <build> <plugins> <plugin> <groupId>org.apache

使用IdentityServer4,在一個ASPNetCore專案中,配置oidcapi的AccessToken兩種認證授權

1.配置兩種認證方式 JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); services.AddAuthentication(options => {

一個django專案-通過命令列pycharm兩種方式

以本機環境為例,ip地址為172.20.16.148,windows平臺,虛擬環境路徑為d:\VirtualEnv,專案存放位置為d:\DjangoProject   命令列方式 1.進入虛擬環境建立專案django-admin startproject projectname 專案的存

Eclipse的下載安裝以及建立第一個Java專案

Eclipse的下載和安裝 下載地址:http://www.eclipse.org/downloads/eclipse-packages/ 1、選擇Eclipse IDE for Java Developers,根據自己安裝的JDK, 決定是下載32位還是64位

node npm 版本更新

node 版本更新 由於公司要用NG-ZORRO,於是我就跑到官網先看看demo,怎麼構建專案,執行的過程中發現了問題 問題描述 執行官網構建專案命令 安裝腳手架工具# $ npm install -g @angular/cli 建立一個專案 $ ng new PROJECT-NAME You a