這篇文章主要介紹Okhttp、Retrofit進(jìn)度怎么獲取,文中介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們一定要看完!
成都創(chuàng)新互聯(lián)公司是專業(yè)的開化網(wǎng)站建設(shè)公司,開化接單;提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè),網(wǎng)頁設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行開化網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!
起因
對于廣大Android開發(fā)者來說,最近用的最多的網(wǎng)絡(luò)庫,莫過于Okhttp啦(Retrofit依賴Okhttp)。
Okhttp不像SDK內(nèi)置的HttpUrlConnection一樣,可以明確的獲取數(shù)據(jù)讀寫的過程,我們需要執(zhí)行一些操作。
介紹
Retrofit依賴Okhttp、Okhttp依賴于Okio。那么Okio又是什么鬼?別急,看官方介紹:
Okio is a library that complements java.io and java.nio to make it much easier to access, store, and process your data.
翻譯過來就是,Okio是一個(gè)實(shí)現(xiàn)了java.io和java.nio的一個(gè)類庫,它讓連接,存儲(chǔ),處理你的數(shù)據(jù)更加輕松~(Okio既是讀寫相關(guān)類庫,獲取進(jìn)度要從Okio入手)。
好吧,對于廣大開發(fā)者來說,內(nèi)心是這樣的:TM又要看你文檔和用例,按你規(guī)則走,輕松個(gè)毛啊!
其實(shí),讀下API,看下Example熟悉后,人家設(shè)計(jì)的還是很棒噠。
廢話不多說,先看效果。
效果
實(shí)際代碼:
//添加下載攔截器(this參數(shù)是實(shí)現(xiàn)下載進(jìn)度接口的對象) mDownClient = new OkHttpClient.Builder() //只需要一行代碼就行了 .addNetworkInterceptor(new DownloadInterceptor(this)) .build(); //添加上傳攔截器(this參數(shù)是實(shí)現(xiàn)上傳回調(diào)接口的對象) mUploadClient = new OkHttpClient.Builder() //只需要一行代碼就行了 .addNetworkInterceptor(new UploadInterceptor(this)) .build();
你只需要一行代碼是不行的!我為什么行?因?yàn)檫@是我寫的封裝類庫啊~(最后放地址)
思路
Okhttp依賴Okio進(jìn)行了數(shù)據(jù)的讀寫動(dòng)作,我們需要找到Okio進(jìn)行處理。那么,如何加上呢?
Okhttp可以添加Interceptor(攔截器),我們可以通過攔截器的接口方法,獲取對應(yīng)的responseBody、requestBody對象進(jìn)行操作。然后我們就獲取了讀寫相關(guān)的實(shí)現(xiàn)方法。具體實(shí)現(xiàn)是通過Source、Sink對象。
Source官方解釋:Supplies a stream of bytes. Use this interface to read data from wherever it's located。
Sink官方解釋:Receives a stream of bytes. Use this interface to write data wherever it's needed。
一句話概括:Source對象是對輸入流的包裝(下載讀數(shù)據(jù)),Sink是對輸出流的包裝(寫數(shù)據(jù)上傳)。
實(shí)現(xiàn)
根據(jù)需要添加下載、上傳Interceptor
//添加下載攔截器(this參數(shù)是實(shí)現(xiàn)下載進(jìn)度接口的對象) mDownClient = new OkHttpClient.Builder() .addNetworkInterceptor(new DownloadInterceptor(this)) .build(); //添加上傳攔截器(this參數(shù)是實(shí)現(xiàn)上傳回調(diào)接口的對象) mUploadClient = new OkHttpClient.Builder() .addNetworkInterceptor(new UploadInterceptor(this)) .build();
攔截器具體實(shí)現(xiàn)
//下載攔截器 public class DownloadInterceptor implements Interceptor { private OnDownloadListener mListener; public DownloadInterceptor( OnDownloadListener listener) { mListener = listener; } @Override public Response intercept(Chain chain) throws IOException { //封裝ressponse對象 Response response = wrapResponse(chain.proceed(chain.request())); return response; } private Response wrapResponse(Response response) { if (response == null || response.body() == null) { return response; } //獲取處理后的response對象 Response wrapResponse = getWrapResponse(response); return wrapResponse; } private Response getWrapResponse(Response response) { ProgressInfo info = new ProgressInfo(); info.setTime(System.currentTimeMillis()+""); info.setUrl(response.request().url().toString()); Response.Builder builder = response.newBuilder(); //封裝responseBody,傳入相關(guān)參數(shù),獲取進(jìn)度數(shù)據(jù)回調(diào) return builder.body(new WrapResponseBody(response.body(),info,mListener)).build(); } } --------------------------------------分割--------------------------------------- //上傳攔截器 public class UploadInterceptor implements Interceptor { private OnUploadListener mListener; public UploadInterceptor(OnUploadListener listener) { mListener = listener; } @Override public Response intercept(Chain chain) throws IOException { //封裝request對象 Request request = wrapRequest(chain.request()); Response response = chain.proceed(request); return response; } private Request wrapRequest(Request request) { if (request == null || request.body() == null) { return request; } Request.Builder builder = request.newBuilder(); ProgressInfo info = new ProgressInfo(); HttpUrl url = request.url(); info.setUrl(url.toString()); info.setTime(System.currentTimeMillis()+""); //封裝requestBody,傳入?yún)?shù),獲取數(shù)據(jù)進(jìn)度回調(diào) builder.method(request.method(),new WrapRequestBody(request.body(),info,mListener)); return builder.build(); } } responseBody、requestBody相關(guān)實(shí)現(xiàn) //繼承ResponseBody實(shí)現(xiàn)具體方法 public class WrapResponseBody extends ResponseBody { private Handler mHandler = new Handler(Looper.getMainLooper()); private ResponseBody mResponseBody; private OnDownloadListener mListener; private ProgressInfo mInfo; private BufferedSource mBufferedSource; private boolean mDoProgress; //傳入進(jìn)度,以及監(jiān)聽對象 public WrapResponseBody(ResponseBody responseBody, ProgressInfo info, OnDownloadListener listener) { mResponseBody = responseBody; mInfo = info; mListener = listener; } @Nullable @Override public MediaType contentType() { //接口方法,返回類型 return mResponseBody.contentType(); } @Override public long contentLength() { long contentLength = mResponseBody.contentLength(); //gzip壓縮格式會(huì)返回-1,目前處理是在請求頭信息指定("Accept-Encoding","identity")表示不壓縮 if (contentLength == -1) { mDoProgress = false; mHandler.post(new Runnable() { @Override public void run() { //切換線程,進(jìn)行失敗回調(diào) mListener.onDownLoadGetContentLengthFail(mInfo); } }); } else { mDoProgress = true; } return contentLength; } @Override public BufferedSource source() { //WrapSource(繼承ForwardingSource,F(xiàn)orwardingSource實(shí)現(xiàn)了Source接口) if (mBufferedSource == null) { mInfo.setContentLength(contentLength()); //傳入?yún)?shù),讀取具體進(jìn)度信息,并回調(diào) WrapSource wrapSource = new WrapSource(mResponseBody.source(), mInfo, mListener,mDoProgress); mBufferedSource = Okio.buffer(wrapSource); } return mBufferedSource; } } --------------------------------------分割--------------------------------------- //繼承ResquestBody實(shí)現(xiàn)具體方法 public class WrapRequestBody extends RequestBody { private RequestBody mRequestBody; private OnUploadListener mListener; private ProgressInfo mInfo; private boolean mDoProgress; private Handler mHandler = new Handler(Looper.getMainLooper()); //傳入進(jìn)度,以及監(jiān)聽對象 public WrapRequestBody(RequestBody requestBody, ProgressInfo info, OnUploadListener listener) { mRequestBody = requestBody; mListener = listener; mInfo = info; } @Override public MediaType contentType() { //接口方法,返回類型 return mRequestBody.contentType(); } @Override public long contentLength() throws IOException { try { //上傳內(nèi)容長度,有異常走failWrok處理 long l = mRequestBody.contentLength(); mDoProgress = true; return l; } catch (IOException e) { e.printStackTrace(); failWork(); return -1; } } //進(jìn)行失敗處理 private void failWork() { mDoProgress = false; mHandler.post(new Runnable() { @Override public void run() { //切換線程,回調(diào)失敗信息 mListener.onUploadGetContentLengthFail(mInfo); } }); } @Override public void writeTo(BufferedSink sink) throws IOException { mInfo.setContentLength(contentLength()); // WrapSink (繼承ForwardingSink,F(xiàn)orwardingSink實(shí)現(xiàn)了Sink接口) ///傳入?yún)?shù),讀取具體進(jìn)度信息,并回調(diào) WrapSink wrapSink = new WrapSink(sink, mInfo, mListener, mDoProgress); BufferedSink buffer = Okio.buffer(wrapSink); mRequestBody.writeTo(buffer); buffer.flush(); } } WrapSource、WrapSink相關(guān)實(shí)現(xiàn) //繼承ForwardingSource 實(shí)現(xiàn)具體方法 public class WrapSource extends ForwardingSource { private Handler mHandler = new Handler(Looper.getMainLooper()); private Source mSource; private ProgressInfo mInfo; private OnDownloadListener mListener; private boolean mDoProgress; public WrapSource(Source source, ProgressInfo info, OnDownloadListener listener, boolean doProgress) { //傳入源Source、進(jìn)度信息、監(jiān)聽進(jìn)度等信息。 super(source); mSource = source; mInfo = info; mListener = listener; //傳入是否繼續(xù)執(zhí)行回調(diào)boolean參數(shù),如果之前執(zhí)行有異常,則不再繼續(xù)執(zhí)行回調(diào) mDoProgress = doProgress; } @Override public long read(Buffer sink, long byteCount) throws IOException { //獲取具體進(jìn)度信息,來到了熟悉的具體IO long read = super.read(sink, byteCount); if (read != -1) { long l = mInfo.getCurrentLength() + read; mInfo.setCurrentLength(l); mHandler.post(new Runnable() { @Override public void run() { if (mDoProgress) { //切換到主線程,回調(diào)數(shù)據(jù) mListener.onDownLoadProgress(mInfo); } } }); } return read; } } --------------------------------------分割--------------------------------------- //繼承ForwardingSink 實(shí)現(xiàn)具體方法 public class WrapSink extends ForwardingSink { private Handler mHandler = new Handler(Looper.getMainLooper()); public OnUploadListener mListener; public ProgressInfo mInfo; public boolean mDoProgress; public WrapSink(Sink delegate, ProgressInfo info, OnUploadListener listener, boolean doProgress) { //傳入源Source、進(jìn)度信息、監(jiān)聽進(jìn)度等信息。 super(delegate); mInfo = info; mListener = listener; //傳入是否繼續(xù)執(zhí)行回調(diào)boolean參數(shù),如果之前執(zhí)行有異常,則不再繼續(xù)執(zhí)行回調(diào) mDoProgress = doProgress; } @Override public void write(Buffer source, long byteCount) throws IOException { super.write(source, byteCount); //獲取具體進(jìn)度信息,來到了熟悉的具體IO long l = mInfo.getCurrentLength() + byteCount; mInfo.setCurrentLength(l); mHandler.post(new Runnable() { @Override public void run() { if (mDoProgress) { //切換到主線程,回調(diào)數(shù)據(jù) mListener.onUpLoadProgress(mInfo); } } }); } }
以上是“Okhttp、Retrofit進(jìn)度怎么獲取”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識(shí),歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
名稱欄目:Okhttp、Retrofit進(jìn)度怎么獲取
地址分享:http://aaarwkj.com/article40/jjpdeo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、ChatGPT、網(wǎng)站營銷、關(guān)鍵詞優(yōu)化、網(wǎng)站改版、標(biāo)簽優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)