Retrofit+RXJavaは、すでに市場で最も主流のネットワークフレームワークです。通常のネットワークリクエストを行うために使用するのは非常に簡単です。レトロフィットを使用してファイルをアップロードしてファイルをダウンロードしましたが、レトロフィットを使用してダウンロードを使用してもデフォルトでは進行状況コールバックをサポートしていないことがわかりましたが、製品はファイルをダウンロードするときにダウンロードの進行状況を表示する必要があるため、入力する必要があります。
次に、それを一緒にカプセル化し、Retrofit+RXJavaを使用して、進行状況のあるファイルをダウンロードしましょう。
Github:jsdownload
最初にUML図を見てみましょう:
あなたはそれに対処する方法がわからないかもしれません。心配しないでください、段階的にそれを取りましょう:
1.依存を追加する必要があります
compile 'io.reactivex:rxjava:1.1.0'compile' io.reactivex:rxandroid:rxandroid:1.1.0'compile 'com.squareup.retrofit2:2.0.0-beta4'compile' com.com.squareup.retrofit2:2.0.0.0-betile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'compile' com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4 ''
使用するときは、バージョン番号に注意してください
2。コールバックを書き込みます
/***説明:2017/11/30にJIAによって作成された進行状況コールバックをダウンロードします。 *人々がそれを行うことができる理由は、彼らが自分ができると信じているからですboid onprogress(int progress); void onfinishdownload(); void onfail(string errorinfo);}
言うまでもなく、ダウンロードされたコールバックには、少なくとも4つのコールバック方法があります。
進行状況の割合はonprogressメソッドで返され、障害理由はonfailで返されることに注意してください。
3.応答ボディを書き換えて、ダウンロード率を計算します
/***説明:2017/11/30にJIAによって作成された進行状況でリクエストボディをダウンロードします。 *人々がそれを行うことができる理由は、彼らが彼らができると信じているからです*/パブリッククラスjsresponsebodyはresponsebodyを拡張する{private responsbody responsebody; Private JSDownLoadListener DownloadListener; // bufferedsourceは、okioライブラリの入力ストリームであり、ここでは入力ストリームとして使用されます。 Private BufferedSource BufferedSource; public jsresponsebody(responsedody responsebody、jsdownloadlistener downloadlistener){this.responsebody = responsebody; this.downloadListener = downloadListener; } @Override public mediatype contentType(){return Responsebody.contentType(); } @Override public long contentlength(){return ressonsbody.contentlength(); } @Override public bufferedSource source(){if(bufferedsource == null){bufferedsource = okio.buffer(source(responsbody.source())); } return bufferedsource; } private source source(source source){return new ForwardingSource(source){long totalbytesRead = 0L; @Override public long read(バッファシンク、ロングバイテクター)スローioException {long bytesRead = super.read(sink、bytecount); // read()このソースが使い果たされている場合は、read()readの数を返します。 TotalByTesRead += bytesRead!= -1? BytesRead:0; log.e( "download"、 "read:"+(int)(totalbytesRead * 100 / responsebody.contentlength())); if(null!= downloadListener){if(bytesRead!= -1){downloadListener.OnProgress((int)(totalbyTesRead * 100 / ResponseBody.ContentLength()); }} bytesRead; }}}; }}コンストラクト内のネットワーク要求のために、ResponseBodyとJSDownLoadListenerを渡します。
ここでのコアはソースメソッドです。このメソッドは、フォワードシングルスオブジェクトを返し、読み取り方法をオーバーライドし、読み取りメソッドの割合を計算し、コールバックのダウンロードListenerに渡します。
4。インターセプター
応答ボディのみをカプセル化するだけでは不十分です。重要なのは、要求された応答ボディを取得する必要があることです。ここでは、インターセプターを使用します。
/***説明:2017/11/30にJIAによって作成された進行状況のインターセプターをダウンロードします。 *人々がそれを行うことができる理由は、彼らが彼らができると信じているからですpublic jsdownloadInterceptor(jsdownloadListener downloadListener){this.downloadListener = downloadListener; } @Override public Response Intercept(チェーンチェーン)IoException {Response Response = Chain.ProCeche(Chain.Request()); RESPORSIN.NEWBUILDER()。BODY(new JSResponseBody(Response.Body()、DownloadListener))。build(); }}通常、インターセプターは、リクエストまたは応答ヘッダー情報を追加、削除、または変換するために使用されます。
インターセプトメソッドインターセプトでカプセル化されたばかりの応答ボディを返します。
5。ネットワークリクエストサービス
/** *説明: * 2017/11/30にJIAによって作成されました。 *人々がそれを行うことができる理由は、彼らが彼らができると信じているからです
知らせ:
ここで、@urlは完全なダウンロードURLに合格します。 @Streaming Annotationメソッドをインターセプトする必要はありません
6.最終リクエストの開始
/** 1。説明:2017/11/30にJIAによって作成されたツールクラス2をダウンロードします。 3。人々がそれを行うことができる理由は、彼らができると信じているからです*/public class downloadutils {private static final string tag = "downloadutils";プライベート静的最終int default_timeout = 15;プライベートレトロフィットレトロフィット。プライベートJSDownLoadListenerリスナー。プライベートストリングベースール;プライベート文字列downloadurl; public downloadutils(string baseurl、jsdownloadlistenerリスナー){this.baseurl = baseurl; this.listener =リスナー; jsDownLoadInterceptor minterceptor = new JSDownLoadInterceptor(リスナー); okhttpclient httpclient = new okhttpclient.builder().addInterceptor(minterceptor).retryonconnectionFailure(true).connecttimeout(default_timeout、timeUnit.seconds).build(); RETROFIT = new Retrofit.Builder().Baseurl(baseurl).client(httpclient).addcalladapterfactory(rxjavacalladapterfactory.create()).build(); } / ** *ダウンロードを開始 * * @param url * @param filepath * @param subscriber * / public void download(@nonnull string url、final string filepath、subscriber subscriber){ristener.onstartdownload(); // subscribeon()が呼び出される前にコードのスレッドを変更しますinputstream call(responsebody responsebody){retunt responsebody.bytestream(); .observeon(androidschedulers.mainthread()).subscribe(subscriber); } / ** *入力ストリームをファイルに書き込みます * * @param inputstring * @param filepath * / private void writefile(inputstream inputstring、string filepath){file file = new file(filepath); if(file.exists()){file.delete(); } fileoutputStream fos = null; try {fos = new fileoutputStream(file); byte [] b = new byte [1024]; int len; while((len = inputstring.read(b))!= -1){fos.write(b、0、len); } inputstring.close(); fos.close(); } catch(filenotfoundexception e){ristener.onfail( "filenotfoundexception"); } catch(ioException e){ristener.onfail( "ioException"); }}}もちろん、ダウンロードコールバックの各場所にも注意を払う必要があります。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。