❶ 為什麼okhttpclient不能builder
一、概述
最近在群里聽到各種討論okhttp的話題,可見okhttp的口碑相當好了。再加上Google貌似在6.0版本裡面刪除了HttpClient相關API,對於這個行為不做評價。為了更好的在應對網路訪問,學習下okhttp還是蠻必要的,本篇博客首先介紹okhttp的簡單使用,主要包含:
一般的get請求
一般的post請求
基於Http的文件上傳
文件下載
載入圖片
支持請求回調,直接返回對象、對象集合
支持session的保持
最後會對上述幾個功能進行封裝,完整的封裝類的地址見:https://github.com/hongyangAndroid/okhttp-utils
使用前,對於Android Studio的用戶,可以選擇添加:
compile 'com.squareup.okhttp:okhttp:2.4.0'1
或者Eclipse的用戶,可以下載最新的jar okhttp he latest JAR ,添加依賴就可以用了。
注意:okhttp內部依賴okio,別忘了同時導入okio:
gradle: compile 'com.squareup.okio:okio:1.5.0'
最新的jar地址:okio the latest JAR
二、使用教程
(一)Http Get
對了網路載入庫,那麼最常見的肯定就是http get請求了,比如獲取一個網頁的內容。
//創建okHttpClient對象
OkHttpClient mOkHttpClient = new OkHttpClient();
//創建一個Request
final Request request = new Request.Builder()
.url("https://github.com/hongyangAndroid")
.build();
//new call
Call call = mOkHttpClient.newCall(request);
//請求加入調度
call.enqueue(new Callback()
{
@Override
public void onFailure(Request request, IOException e)
{
}
@Override
public void onResponse(final Response response) throws IOException
{
//String htmlStr = response.body().string();
}
}); 以上就是發送一個get請求的步驟,首先構造一個Request對象,參數最起碼有個url,當然你可以通過Request.Builder設置更多的參數比如:header、method等。
然後通過request的對象去構造得到一個Call對象,類似於將你的請求封裝成了任務,既然是任務,就會有execute()和cancel()等方法。
最後,我們希望以非同步的方式去執行請求,所以我們調用的是call.enqueue,將call加入調度隊列,然後等待任務執行完成,我們在Callback中即可得到結果。
看到這,你會發現,整體的寫法還是比較長的,所以封裝肯定是要做的,不然每個請求這么寫,得累死。
ok,需要注意幾點:
onResponse回調的參數是response,一般情況下,比如我們希望獲得返回的字元串,可以通過response.body().string()獲取;如果希望獲得返回的二進制位元組數組,則調用response.body().bytes();如果你想拿到返回的inputStream,則調用response.body().byteStream()
看到這,你可能會奇怪,竟然還能拿到返回的inputStream,看到這個最起碼能意識到一點,這里支持大文件下載,有inputStream我們就可以通過IO的方式寫文件。不過也說明一個問題,這個onResponse執行的線程並不是UI線程。的確是的,如果你希望操作控制項,還是需要使用handler等,例如:
@Override
public void onResponse(final Response response) throws IOException
{
final String res = response.body().string();
runOnUiThread(new Runnable()
{
@Override
public void run()
{
mTv.setText(res);
}
});
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
我們這里是非同步的方式去執行,當然也支持阻塞的方式,上面我們也說了Call有一個execute()方法,你也可以直接調用call.execute()通過返回一個Response。
(二) Http Post 攜帶參數
看來上面的簡單的get請求,基本上整個的用法也就掌握了,比如post攜帶參數,也僅僅是Request的構造的不同。
Request request = buildMultipartFormRequest(
url, new File[]{file}, new String[]{fileKey}, null);
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add("username","張鴻洋");
Request request = new Request.Builder()
.url(url)
.post(builder.build())
.build();
mOkHttpClient.newCall(request).enqueue(new Callback(){});12345678910
大家都清楚,post的時候,參數是包含在請求體中的;所以我們通過FormEncodingBuilder。添加多個String鍵值對,然後去構造RequestBody,最後完成我們Request的構造。
後面的就和上面一樣了。
(三)基於Http的文件上傳
接下來我們在介紹一個可以構造RequestBody的Builder,叫做MultipartBuilder。當我們需要做類似於表單上傳的時候,就可以使用它來構造我們的requestBody。
File file = new File(Environment.getExternalStorageDirectory(), "balabala.mp4");
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"username\""),
RequestBody.create(null, "張鴻洋"))
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"mFile\";
filename=\"wjd.mp4\""), fileBody)
.build();
Request request = new Request.Builder()
.url("http://192.168.1.103:8080/okHttpServer/fileUpload")
.post(requestBody)
.build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback()
{
//...
});2526
上述代碼向伺服器傳遞了一個鍵值對username:張鴻洋和一個文件。我們通過MultipartBuilder的addPart方法可以添加鍵值對或者文件。
其實類似於我們拼接模擬瀏覽器行為的方式,如果你對這塊不了解,可以參考:從原理角度解析Android (java) http 文件上傳
ok,對於我們最開始的目錄還剩下圖片下載,文件下載;這兩個一個是通過回調的Response拿到byte[]然後decode成圖片;文件下載,就是拿到inputStream做寫文件操作,我們這里就不贅述了。
關於用法,也可以參考泡網OkHttp使用教程
接下來我們主要看如何封裝上述的代碼。
三、封裝
由於按照上述的代碼,寫多個請求肯定包含大量的重復代碼,所以我希望封裝後的代碼調用是這樣的
附上出處鏈接:http://blog.csdn.net/lmj623565791/article/details/47911083
❷ android app開發中常用到哪些開源框架
1.Framework 7
來自iDangero.us —自版本.0在一年前發布以來,Framework就一直是開發iOS應用程序的最佳選擇之一。由於它提供對安卓的支持,如果你先從iOS入手,但隨後構建具有類似iOS外觀感覺的安卓版本,它也是個不錯的選擇。功能特性包括:Material Design用戶界面、原生滾動、1:1頁面動畫、自定義DOM庫以及XHR緩存和預裝入。
3.jQuery Mobile
來自jQuery基金會— 這種成熟的輕量級框架基於jQuery,缺少本文中介紹的大多數程序包具有的許多高級功能,不過它仍擁有一群龐大的忠實用戶。雖然它提供了語義標記、漸進式改進、主題化設計和PhoneGap/Cordova支持之類的功能,但是在類似原生系統的功能和性能或者高級用戶界面方面乏善可陳。另一方面,它又很簡單,這意味著「編寫一次,到處運行」是常常可以實現的目標;對於還需要在Windows Phone和黑莓上運行的簡單應用程序而言,它也是個不錯的選擇。
2.Ionic
來自Ionic — 這種流行的跨平台框架基於Sass CSS擴展語言,使用起來相當容易,不過它還能集成用於構建更高級應用程序的Angularjs。Ionic提供了一個豐富的庫,包括針對移動設備優化的HTML、CSS和JS CSS組件、手勢及工具,可與預定義的組件協同工作。命令行介面提供了模擬器、實時重裝和日誌等功能。還有一個基於Cordova的應用程序包裝器。
4.Kendo UI
來自Telerik — 這種基於jQuery的HTML5/Java框架既有開源版,又有商業版。對企業用戶友好的Kendo UI提供了種類豐富的用戶界面窗口組件和插件。它最廣為人知的地方就是擁有無數具有Material Design風格的預構建主題,另外還有一個主題構建器,可用於構建自定義主題。其他功能特性包括:Angular和Bootstrap UI集成以及性能優化。
6.Native
來自Telerik —顧名思義,Native專注於原生用戶體驗開發,但是它提供了跨安卓和iOS的跨平台代碼共享支持。該軟體使用現有的原生用戶界面庫,用戶界面由Java、XML或視情況而定的Angular來描述。然而,使用起來,它不如Telerik更傳統的跨平台Kendo UI框架來得容易。
5.Mobile Angular UI
來自Maurizio Casimirri —這個開源項目將AngularJS和經過修改的推特Bootstrap合並到了一個移動用戶界面框架。據說它保留了Bootstrap 3的大部分語法,因而更容易實現從Web應用程序向移動應用程序的移植,同時增添了Bootstrap缺失的許多組件,比如切開關、覆蓋、側邊欄、可滾動區域以及固定位置的導航條。庫包括fastclick.js和overthrow.js。
7.Onsen UI
來自Asial Corp. — Onsen基於HTML和CSS而建,旨在與並非預先集成的PhoneGap和Cordova協同運行。它還可以與Angular和jQuery協同運行。顧名思義,該程序強調用戶界面開發,並提供了一系列廣泛的基於Web的用戶界面組件和特性,比如表格的雙列視圖。(然而,仍然缺少Material Design。)這個文檔完備的程序針對這樣的jQuery Mobile用戶:既需要易於使用,又想要更多的功能、更高的性能和更豐富的用戶界面特性。總部位於東京的Asial正在開發一種拖放式GUI工具,該公司還開發和維護Monaca。
9.Sencha Touch
來自Sencha — Sencha的成熟的、面向企業的HTML5/Java框架既有開源版,又有商業版。Sencha建立於ExtJS的基礎上,能夠獲得類似原生的性能。它為HTML5提供了可視化應用程序構建器,另外還提供了重復使用自定義組件的功能。原生包裝器簡化了分發到Google Play等應用程序商店的工作。
8.React Native
來自Facebook — React Native是一種開源框架,從Facebook的React Java框架派生而來,眾所周知,Java框架取代了早些時候的HTML5基礎。顧名思義,這個面向iOS的高端程序與其說是一種跨平台框架,還不如說是原生程序包裝器,但是由於新增了對安卓的支持,它很適合我們的要求,因為你實際上只要用Java編寫一次代碼,就能移植到這兩個平台。目前,只有OS X桌面得到全面支持,不過也有試驗性的Linux和Windows版本面向安卓開發。
10.Titanium
來自Appcelerator —不像那些比較偏向Web的框架,Titanium使用Java來構建原生代碼,聲稱有望提升性能。這種基於Node.js的軟體開發工具包(SDK)為iOS、安卓、Windows、黑莓和HTML5提供了5000多個API。Titanium更廣為人知的地方是性能和豐富的功能特性,而不是易用性。軟體是開源,不過只要你不發布你的應用程序,功能齊全的免費版可以免費享用,眼下你每月至少得支付39美元。
❸ 網路請求框架-OkHttp原理解析
okhttp是square公司貢獻的一個處理網路請求的開源框架,是目前Android開發使用最廣泛的一個網路框架,從Android4.4開始,httpURLconnection的底層實現採用的就是okhttp。內部實現就是利用java基礎,對socket進行封裝,實現http通信。最重要的兩個關鍵點就是分發器和5個攔截器。
分發器 就是內部維護隊列和線程池,完成請求分配,總結就是用於對非同步任務加入隊列管理,然後判斷條件,控制數量,加入線程池執行非同步請求任務。
五個默認攔截器 就是利用責任鏈模式對網路請求進行層層處理,完成整個請求過程,簡單總結如下。
1.橋接攔截器對用戶發出的請求添加缺少的請求配置欄位,比如keep-alive等
2.緩存攔截器就是查詢有沒有符合判斷條件的已緩存的網路請求,執行復用,直接返回response
3.連接攔截器就是創建請求,加入連接器 或者訪問連接池,根據條件判斷,是否能懟已創建的tcp請求進行復用
4.請求伺服器攔截器就是對scoket進行操作,請求網路訪問伺服器,返回response,
5.重試和重定向攔截器就是對返回的response進行code判斷,決定是否要重試或者重定向操作。
1.支持http2.0版本,並且允許對同一主機的所有請求共享一個套接字
2.即使不是http2.0版本,通過連接池,減少請求延遲
3.默認使用Gzip 壓縮數據
4.響應緩存,避免重復請求網路
最簡單的http請求案例
1.利用建造者模式構建okHttpClient實例對象,構建過程中可以動態配置參數,請求時間,響應時間,緩存信息等。
2.創建Request對象,設置請求方式,鏈接地址,參數等信息。
3.把request對象,傳給client,通過newCall函數,得到RealCall對象。
4.RealCall 分為同步和非同步執行
5.同步執行時,分發器只是做個記錄,把請求任務加到隊列中,然後直接通過攔截器訪問伺服器,返回response。
6.非同步執行
6.1先對非同步任務進一步封裝,把任務放到AsyncCall對象中
2.分發器 把 封裝後的非同步任務 添加到等待運行的隊列中
7. 通過攔截器,獲取response
okhttp 默認提供5個攔截器 重試重定向攔截器,橋接攔截器,緩存攔截器,連接攔截器,訪問伺服器攔截器。還可以自定義攔截器。
自定義攔截器分為應用攔截器(通過addInterceptor 添加)和網路攔截器(通過addNetworkInterceptor攔截)
攔截器採用責任鏈的設計默認,讓請求者和處理者解耦,最終請求從前往後,響應從後往前。
首先先判斷用戶是否取消了請求,如果沒有取消,就把請求交個橋接攔截器。
在獲得響應結果response的時候根據響應碼,判斷是否需要重試或者重定向, 重試不限制次數,重定向最多20次 ,如果需要重試或者重定向,那麼會再一次重新執行所有攔截器。
有如下幾種情況不會重試:IO異常,線路異常,配置client實例時配置不允許重試,協議異常,證書異常等等。
先獲取用戶發送的請求,判斷條件用戶是否已經配置過請求頭欄位,若用戶沒有配置,則將http協議必備的請求頭欄位補齊,比如Content-Type,Content-Length等,然後交給下一個攔截器。
在獲得響應結果response之後,調用保存cookie的介面(也可以在配置client的時候,設置cookjar進行cookie回調數據),並且解析gzip數據
獲取結果之後,對cookie進行保存,對返回的數據進行gzip解壓
就是根據緩存策略從緩存中查找是否有合適的緩存response,如果有合適的緩存,直接返回給請求任務,不在繼續執行後面的攔截器。
獲得響應結果response後,根據條件判斷,決定是否要緩存。
維護一個連接池,負責對連接的服務。在把請求交給下一個攔截器之前。會先在連接池中找到一個合適的連接(滿足適配條件相同,並且沒有正在被使用)或者新建一個連接,並且接入連接池,獲得對應的socket流,把請求交給下一個攔截器。獲得response結果後不會進行額外的處理。
連接池, 也稱之為對象池,主要用來存放request請求連接,內部維護了一個LinkedQueue隊列用來存放請求。在添加新的請求對象時,都會執行一個周期性任務,用以對連接池進行清理操作。
1.隊列長度超過5,清理最近未被使用連接,LRE演算法
2.存儲的連接,5分鍾未被復用,清理
拿到上一個攔截器返回的請求,真正的與伺服器進行通信,向伺服器發送數據,解析讀取響應的數據,返回給上一個攔截器。
1.創建request =>OkHttpClient=>RealCall()
2.同步執行 ,分發器添加同步任務,執行攔截器,訪問伺服器,返回reponse,觸發非同步分發流程。
3.非同步執行 ,封裝任務= >AsyncCall ,實現runnable介面。添加任務到非同步任務等待隊列,執行分發任務,判斷非同步任務是否能加入正在執行的非同步任務隊列,滿足兩個條件
同時執行的非同步任務數量不得大於64個
對同一個主機的訪問任務,最多不得大於5個
4.加入正在執行的非同步任務隊列,通過線程池執行任務,經過5個默認攔截器訪問伺服器,返回response,執行非同步任務分發。
分發器工作 分為同步任務和非同步任務兩種
同步任務 就是把任務加入同步任務隊列,加個標記,執行結束之後,觸發非同步任務的分發操作。
非同步任務 先封裝任務到asyncCall對象,實現了runnable介面。把任務加入等待執行隊列,執行分發操作。
先遍歷等待任務隊列,判斷是否符合加入正在運行的非同步任務隊列,要同時滿足兩個條件。
同時執行的非同步任務數量不得大於64個
對同一個主機的訪問任務,最多不得大於5個
當滿足條件後,從等待隊列中刪除任務,把任務加入正在執行的隊列中,通過自定義的線程池,執行任務,任務執行結束後,再次執行分發操作。
攔截器採用了責任鏈設計默認,讓請求者和執行者解耦,請求者只需要將請求發給責任鏈即可,無需關心請求過程和細節。okHttp 默認有5個攔截器,重試重定向攔截器,橋接攔截器,緩存攔截器,連接攔截器,請求服務攔截器。工作細節參考上面攔截器原理分析部分
1.位置的關系,應用攔截器 放在責任鏈最頂端,網路攔截器放在責任鏈倒數第二的位置。所以應用攔截器 最先攔截,最後響應,網路攔截器 倒數第二攔截,第二響應。如果列印請求日誌的情況,應用攔截器列印的是用戶請求信息,經過重試重定向,橋接,緩存,鏈接 等攔截器的層層包裝,網路攔截器列印的是實際請求的信息。
2.應用攔截器一定會被執行,網路攔截器不一定被執行。
利用連接池,緩存所有的有效連接對象。
清理機制:垃圾連接
1.超過5分鍾沒有用過的鏈接
2.超過5個閑置鏈接後,從最久閑置的鏈接開始執行清理(LRU)
❹ Android網路請求庫【OkHttp4.9.3】基本用法與原理分析
OkHttp是一套處理 HTTP 網路請求的依賴庫,由 Square 公司設計研發並開源,目前可以在 Java 和 Kotlin 中使用。對於 Android App 來說,OkHttp 現在幾乎已經占據了所有的網路請求操作,Retrofit + OkHttp實現網路請求似乎成了一種標配。因此它也是每一個 Android 開發工程師的必備技能,了解其內部實現原理可以更好地進行功能擴展、封裝以及優化。
OkHttp的高效性體現在:
第一步:創建OkHttpClient,創建OkHttpClient有兩種方式:
OkHttpClient提供了豐富的配置方法,例如添加攔截器、指定連接池、設置請求超時等等。
第二步:創建請求
使用Request.Builder() 構建Request實例
第三步:發起網路請求
OkHttp支持同步和非同步兩種請求方式
OkHttp的使用方法非常簡單,三步操作就可以發起一個簡單的同步或非同步請求。我們也可以很輕松地對網路請求進行配置,例如添加請求頭、設置請求方式、設置請求超時等等,這些配置參數會在源碼分析過程中詳細介紹。
現在我們已經學會了三步操作發起網路請求,接下來以這三個步驟為切入點,深入到源碼中學習OkHttp的實現原理,廢話少說馬上開車。
OkHttpClient創建方式有兩種,我們看看兩種方式有什麼區別。
第一種直接使用默認構造函數,內部依然是使用建造者模式
第二種使用建造者模式
兩種方式最終都是調用構造函數OkHttpClient(builder:Builder),由參數builder負責所有的參數配置工作。
當您創建單個OkHttpClient實例並將其用於所有 HTTP 調用時,OkHttp 性能最佳。 這是因為每個OkHttpClient都擁有自己的連接池和線程池,重用連接和線程可減少延遲並節省內存。 相反,為每個請求創建一個客戶端會浪費空閑池上的資源。
Request同樣使用建造者模式來創建,這里貼上部分重要源碼,很簡單就不細說了。
OkHttp發起網路請求分為同步請求和非同步請求兩種方式,我們只分析非同步請求流程,因為只要理解了非同步請求過程,基本上也就明白同步請求是怎麼一回事了。
RealCall是連接應用層與網路層的橋梁,負責處理連接、請求、響應和數據流。
Dispatcher維護著一套非同步任務執行策略,分析策略之前先介紹幾個重要概念:
client.dispatcher.enqueue(AsyncCall(responseCallback)) 執行步驟為:
AsyncCall實現了Runnable介面,因此一旦被線程池中的線程處理就會調用它的run()方法:
話休絮煩,我們開始分析攔截器責任鏈:
責任鏈執行流程:首先獲取當前攔截器interceptor,並且調用interceptor.intercept(next)執行攔截器操作。這里的next表示的是index+1後的責任鏈對象,攔截器的intercept()方法內部會調用next.proceed(request)方法再次進入到責任鏈,由於此時index已經加1,所以處理的是下一個攔截器。
如此循環往復,直到處理完責任鏈上最後一個攔截器為止。
注意除最後一個攔截器CallServerInterceptor不會調用chain.proceed(request)方法之外,其他攔截器都應該至少調用一次chain.proceed(request)方法。
為了驗證上面的結論,我們進入到RetryAndFollowUpInterceptor的intercept()方法一探究竟:
可以看到注釋1處重新進入責任鏈處理下一個攔截器。
有興趣可以自行查看最後一個攔截器CallServerInterceptor源碼,此處只給出本人閱讀源碼後得出的結論:
以上就是攔截器責任鏈的工作流程,我們再通過流程圖仔細感受一下。
分析完攔截器責任鏈,我們繼續分析AsyncCall#run()方法:
我們看到,如果()方法成功獲得服務端返回的數據,則調用responseCallback.onResponse(this@RealCall, response)方法完成非同步回調;如果服務端數據獲取失敗(請求異常),則調用responseCallback.onFailure(this@RealCall, canceledException)方法完成非同步回調
需要注意的是,responseCallback回調是在子線程中完成的,所以如果想把數據顯示到UI上,需要切換回主線程進行UI操作。
OkHttp發起網路請求全過程:
【知識點】OkHttp 原理 8 連問
❺ android開發一般都使用什麼框架
開源框架推薦:
網路
* [okhttp](square/okhttp · GitHub)
* [android-async-http](loopj/android-async-http · GitHub)
事件匯流排
* [otto](square/otto · GitHub)
* [EventBus](greenrobot/EventBus · GitHub)
依賴注入
* [Dagger](square/dagger · GitHub)
* [RoboGuice](roboguice/roboguice · GitHub)
* [ButterKnife](JakeWharton/butterknife · GitHub)
圖片
* [Fresco](facebook/fresco · GitHub)
* [Glide](bumptech/glide · GitHub)
* [picasso](square/picasso · GitHub)
資料庫
* [greenDao](greenrobot/greenDAO · GitHub)
* [ormlite](j256/ormlite-android · GitHub)
* [LitePal](LitePalFramework/LitePal · GitHub)
響應式編程
* [RxJava](ReactiveX/RxJava · GitHub)
* [RxAndroid](ReactiveX/RxAndroid: RxJava bindings for An...)
日誌輸出
* [logger](orhanobut/logger: Simple, pretty and powerf...)
* [android-CLog](liaohuqiu/android-CLog)
* [KLog](ZhaoKaiQiang/KLog · GitHub)
* [LogUtils](pengwei1024/LogUtils · GitHub)
崩潰統計平台
* [騰訊bugly](騰訊Bugly - Android Crash(崩潰)_iOS Crash(崩潰)_ANR_卡頓)
* [Crittercism](Crittercism - Developer Home)
* [Crashlytics](The most powerful, yet lightest weight crash reporting solution for iOS and Android
developers.)
架構設計
這個肯定得了解下MVC,MVP,MVVM還有設計模式這些,這里有幾個開源項目推薦下
philm
Movie collection and information app for Android.
Github地址:chrisbanes/philm: Movie collection and info...
SimpleNews
基於Material Design和MVP的新聞客戶端
Github地址:GitHub - liuling07/SimpleNews: 基於Material Design和MVP的新聞客戶端
GankDaily
A application show technical information every working days, use MVP pattern.
Github地址:maoruibin/GankDaily
SimplifyReader
Github地址:GitHub - SkillCollege/SimplifyReader: 一款基於Google Material Design設計開發的Android客戶端,包括新聞簡讀,圖片瀏覽,視頻爽看 ,音樂輕聽以及二維碼掃描五個子模塊。
NBAPlus
Github地址:SilenceDut/NBAPlus · GitHub
PhotoNoter
Github地址:yydct/PhotoNoter
Mei
Github地址:drakeet/Mei: gank.io unofficial client, RxJava & Retrofit
DebugDrawer
Android Debug Drawer for faster development
Github地址:palaima/DebugDrawer · GitHub
ViewServer
Local server for Android's HierarchyViewer
Github地址:romainguy/ViewServer · GitHub
AndroidWiFiADB
IntelliJ/AndroidStudio plugin which provides a button to connect your Android device over WiFi to install, run and debug your applications without a USB connected.
Github地址:https://github.com/pedrovgs/AndroidWiFiADB