A ROTOFIT+RXJAVA já é a estrutura de rede mais convencional do mercado. É extremamente fácil usá -lo para fazer solicitações de rede comuns. Eu já usei o Retrofit para fazer upload de arquivos e baixar arquivos antes, mas achei que o uso do retrofit para download não suporta retornos de chamada de progresso por padrão, mas o produto exige que o progresso do download seja exibido ao baixar arquivos, por isso tenho que entrar nele.
Em seguida, vamos encapsulá -lo juntos e usar o retrofit+rxjava para baixar arquivos com progresso.
Github: JSdownload
Vamos dar uma olhada no diagrama UML primeiro:
Você pode não ter certeza de como lidar com isso. Não se preocupe, vamos dar um passo a passo:
1. É necessário adicionar dependência
Compile 'io.reactivex: rxjava: 1.1.0'Compile' io.reactivex: rxandroid: 1.1.0'Compile 'com.squareup.retrofit2: retrofit: 2.0.0-beta4'Compile' com.squareup.retRofit2: 'com.squareup.retofit2: converter-gson: 2.0.0-beta4'compile' com.squareup.retofit2: adaptador-rxjava: 2.0.0-beta4 '
Preste atenção ao número da versão ao usá -lo
2. Escreva o retorno de chamada
/*** Descrição: Faça o download do retorno de chamada de progresso* criado por Jia em 2017/11/11/30. * A razão pela qual as pessoas podem fazer isso é porque acreditam que podem*/interface pública JSDownloadListener {void OnStartDownload (); vazio onprogress (Int Progress); void onfinishdownload (); void onfail (string errorInfo);}Escusado será dizer que o retorno de chamada baixado deve ter pelo menos quatro métodos de retorno de chamada: comece a baixar, baixar progresso, baixar a conclusão e baixar falhas.
Observe que a porcentagem de progresso é retornada no método OnProgress e o motivo de falha é retornado no OnFail.
3. Reescreva a resposta e calcule a porcentagem de download
/*** Descrição: Download do corpo de solicitação com progresso* criado por Jia em 2017/11/11/30. * A razão pela qual as pessoas podem fazer isso é que acreditam que podem*/classe pública JSResponseBody estende a resposta {Response a resposta privada; Private JSDownloadListener DownloadListener; // buffersource é o fluxo de entrada na biblioteca Okio, que é usada aqui como um insputStream. Private buffersource buffersource; public JSResponseBody (ResponseBodyBodyBody, JSDownloadListener DownloadListener) {this.ResponseBody = ResponseBody; this.DownloadListener = DownloadListener; } @Override public MediaType contentType () {return ResponseBody.ContentType (); } @Override public Long contentLength () {return ResponseBody.ContentLength (); } @Override public bufferSource Source () {if (buffersource == null) {buffersource = okio.buffer (origem (respostabody.source ())); } retornar buffersource; } fonte privada fonte (fonte de origem) {return New ForwardingSource (origem) {Long TotalBytesRead = 0l; @Override Public Long Read (Buffer Sink, Long ByteCount) lança IoException {Long bytesread = super.read (Sink, ByteCount); // read () Retorna o número de bytes leitura, ou -1 se essa fonte estiver esgotada. TotalBytesRead += bytesRead! = -1? bytesread: 0; Log.e ("Download", "Leia:"+ (int) (totalbytesread * 100 / ResponseBody.ContentLength ())); if (null! = DownloadListener) {if (bytesRead! = -1) {DownloadListener.onProgress ((int) (totalbytesread * 100 / ResponseBody.ContentLength ())); }} retornar bytesread; }}}; }}Passe a resposta e o JSDownLoadListener para a solicitação de rede no construto.
O núcleo aqui é o método de origem, que retorna o objeto de ForwardingSource, onde substituímos seu método de leitura, calculamos a porcentagem no método de leitura e o passamos para o listener de download de retorno de chamada.
4. Interceptor
Não basta encapsular apenas a resposta da resposta. A chave é que precisamos obter o corpo de resposta solicitado, aqui usamos o interceptador.
/*** Descrição: Download Interceptor com o Progress* criado por Jia em 2017/11/11/30. * A razão pela qual as pessoas podem fazer isso é que elas acreditam que podem*/public classe jsDownloadInterInterceptor implementa interceptores {private jsDownloadListener DownloadListener; public JSDownloadLoadIntercept (JSDownloadListener DownloadListener) {this.DownloadListener = DownloadListener; } @Override Resposta pública Intercept (cadeia) lança ioexception {resposta resposta = cadeia.proeced (cadeia.Request ()); RETORNO RESPOSTO.NewBuilder (). Body (novo JSResponseBody (Response.Body (), DownloadListener)). Build (); }}Normalmente, os interceptores são usados para adicionar, remover ou converter informações de solicitação ou cabeçalho de resposta.
Retorna o corpo de resposta que acabamos de encapsular no método de interceptação intercepto.
5. Serviço de solicitação de rede
/** * Descrição: * Criado por Jia em 2017/11/30. * A razão pela qual as pessoas podem fazer isso é porque acreditam que podem*/interface pública DownloadService {@streaming @get observável <ResponseBody> Download (@url string url);}Perceber:
Aqui @url deve passar no URL completo do download; Você não precisa interceptar o método de anotação @streaming
6. o início do pedido final
/** 1. Descrição: Download da Ferramenta Classe 2. Criado por Jia em 2017/11/30. 3. A razão pela qual as pessoas podem fazer isso é que elas acreditam que podem*/public classe DownloadUtils {private Static final String tag = "DownloadUtils"; private estático final int default_timeout = 15; retrofit privado retrofit; ouvinte privado jsdownloadlistener; String privada Baseurl; Private String Downloadurl; public DownloadUtils (String Baseurl, JSDownloadListener ouvinte) {this.baseurl = baseurl; this.Listener = ouvinte; JsdownloadLoadInterceptor Minterceptor = novo JSDownLoadInterCorpt (ouvinte); 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 (); } / ** * Inicie o download * * @param url * @param filepath * @param assinante * / public void Download (@Nonnull String URL, Final String FilePath, assinante assinante) {lister.onstartDownload (); // Subscribeon () Altera o encadeamento do código antes de ser chamado // observveon () altera o encadeamento do código após ser chamado ROTROFIT.CREADE (DownloadService.class) .Download (url) .subScribeon (schedulers.io ()) .UnsubScribeon (Schedulers.io () .Map (novo fun1). Call (Responsebodybodybody) {Return ResponseBody.byTestream (); .OBSERVEON (Androidschedulers.Mainthread ()) .Subscribe (assinante); } / ** * Escreva o fluxo de entrada no arquivo * * @param inputString * @param filepath * / private void writefile (inputStream inputString, string filepath) {arquivo file = novo arquivo (filepath); if (file.exists ()) {file.delete (); } FileOutputStream fos = null; tente {fos = new FileOutputStream (arquivo); byte [] b = novo byte [1024]; int len; while ((len = inputString.read (b))! = -1) {fos.write (b, 0, len); } inputString.close (); fos.close (); } catch (filenotfoundException e) {listener.onfail ("fileNotfoundException"); } catch (ioexception e) {ouvinte.onfail ("ioexception"); }}}Obviamente, você também precisa prestar atenção a cada local do retorno de chamada de download.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.