RETROFIT+RXJAVA ya es el marco de red más convencional del mercado. Es extremadamente fácil usarlo para realizar solicitudes de red ordinarias. He usado Retrofit para cargar archivos y descargar archivos antes, pero descubrí que usar Retrofit para descargar no admite las devoluciones de llamada de progreso de forma predeterminada, pero el producto requiere que el progreso de descarga se muestre al descargar archivos, por lo que tengo que entrar en él.
A continuación, encapsulemos y usemos Retrofit+Rxjava para descargar archivos con progreso.
GitHub: JSODOWLOAD
Echemos un vistazo al diagrama UML primero:
Es posible que no esté seguro de cómo lidiar con eso. No te preocupes, vamos a tomar paso a paso:
1. Es necesario agregar dependencia
compilar 'io.reactivex: rxJava: 1.1.0'compile' io.reactivex: rxandroid: 1.1.0'compile 'com.squareup.rrecrofit2: retrofit: 2.0.0-beta4'compile' com.squareup.ruprofit2: retrofit 'Com.SquareUp.RrOfit2: Converter-Gson: 2.0.0-Beta4'Compile' Com.SquareUp.RrOfit2: Adapter-RxJava: 2.0.0-Beta4 '
Presta atención al número de versión al usarlo
2. Escribir devolución de llamada
/*** Descripción: Descargue la devolución de llamada de progreso* Creada por JIA el 2017/11/30. * La razón por la cual las personas pueden hacerlo es porque creen que pueden*/Public Interface JSDownloadListener {void onStartDownload (); vacío on -progress (int progrese); void onfinishDownload (); nulo Onfail (String ErrorInfo);}No hace falta decir que la devolución de llamada descargada debe tener al menos cuatro métodos de devolución de llamada: comenzar a descargar, descargar progreso, descargar la finalización y descargar falla.
Tenga en cuenta que el porcentaje de progreso se devuelve en el método OnProgress y el motivo de la falla se devuelve en OnFail.
3. Reescribe ResponseBody y calcule el porcentaje de descarga
/*** Descripción: Descargar el cuerpo de solicitudes con progreso* creado por JIA el 2017/11/30. * La razón por la cual las personas pueden hacerlo es que creen que pueden*/clase pública JSResponseBody extiende ResponseBody {Response ResponseBody de Body privado; privado jsdownloadListener downloadListener; // BufferedSource es la secuencia de entrada en la biblioteca Okio, que se usa aquí como InputStream. bufferedsource privado bufferedSource; public jsResponseBody (Response ResponseBody, jsdownloadListener downloadListener) {this.ResponseBody = ResponseBody; this.downloadListener = descargarListener; } @Override public Mediatype ContentType () {return ResponseBody.ContentType (); } @Override public Long ContentLength () {return ResponseBody.ContentLength (); } @Override public BufferedSource Source () {if (BufferedSource == NULL) {BufferedSource = Okio.Buffer (Source (ResponseBody.Source ())); } return BufferedSource; } fuente de fuente privada (fuente de fuente) {return New ForwardingSource (fuente) {Long TotalBytesread = 0l; @Override public Long Read (fregadero de búfer, long byteCount) lanza ioexception {long bytesread = super.read (federal, bytecount); // Read () Devuelve el número de bytes leídos, o -1 si esta fuente está agotada. TotalBytesread += bytesread! = -1? bytesread: 0; LOG.E ("Descargar", "Read:"+ (int) (TotalBytesread * 100 / ResponseBody.ContentLength ())); if (null! = downloadListener) {if (bytesread! = -1) {downloadListener.onProgress ((int) (totalBytesRead * 100 / ResponseBody.ContentLength ())); }} return bytesread; }}}; }}Pase el RespuestaBody y JSDloadListener para la solicitud de red en la construcción.
El núcleo aquí es el método de origen, que devuelve el objeto ReenseSource, donde anulamos su método de lectura, calculamos el porcentaje en el método de lectura y lo pasamos a la devolución de llamada Descargar Listener.
4. Interceptor
No es suficiente para encapsular solo el cuerpo de respuesta. La clave es que necesitamos obtener el Solicitado ResponseBody, aquí usamos el Interceptor.
/*** Descripción: Descargar Interceptor con progreso* creado por JIA el 2017/11/30. * La razón por la cual las personas pueden hacerlo es que creen que pueden*/public class jsdownloadinterceptor implementa interceptor {private jsdownloadListener downloadListener; public jsdownloadinterceptor (jsdownloadListener downloadListener) {this.downloadListener = downloadListener; } @Override Public Response Intercept (cadena de cadena) arroja IOException {Respuesta respuesta = Chain.proceed (Chain.Request ()); Respuesta de retorno }}Normalmente, los interceptores se utilizan para agregar, eliminar o convertir información de encabezado de solicitud o respuesta.
Devuelve el respuestas de respuesta que acabamos de encapsular en el método Intercept Intercept.
5. Servicio de solicitud de red
/** * Descripción: * Creado por JIA el 2017/11/30. * La razón por la cual las personas pueden hacerlo es porque creen que pueden*/Public Interface DownloadService {@Streaming @get Observable <ResponseBody> Descargar (@URL String URL);}Aviso:
Aquí @url es pasar la URL de descarga completa; No necesita interceptar el método de anotación @Streaming
6. El comienzo de la solicitud final
/** 1. Descripción: Descargar herramientas Clase 2. Creado por JIA el 2017/11/30. 3. La razón por la cual las personas pueden hacerlo es que creen que pueden*/public class downloadUtils {private static final string tag = "downloadUtils"; Private static final int default_timeout = 15; modernización privada de modernización; oyente privado jsdownloadListener; String de cadena privada BaseUrl; descarga de cadena privada; Public downloadUtils (String BaseUrl, JSDownloadListener Listener) {this.baseUrl = baseUrl; this.listener = oyente; Jsdownloadinterceptor Minterceptor = new JSdownloadInterceptor (oyente); 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 (); } / ** * Iniciar descarga * * @param url * @param filepath * @param suscriptor * / public void descargar (@nonnull string url, string final filePath, suscriptor de suscriptor) {oyente.onstartdownload (); // suscriqueseon () cambia el hilo del código antes de que se llame // ObserveOn () cambia el hilo del código después de que se llame RETROFIT.Create (downloadService.class) .download (url) .subscriteon (programador.io ()) .unSubscriteon (programador Llame (Response ResponseBody) {return ResponseBody.ByTeStream ();}}) .ObServeon (schedulers.Computation ()) // Se usa para calcular la tarea.doonNext (new Action1 <inputStream> () {@Override public void Call (InputStream InputStream) {WriteFile (inputStream, FilePath);}}) .observeon (AndroidSchedulers.Mainthread ()) .subscribe (suscriptor); } / ** * Escriba la transmisión de entrada en el archivo * * @param inputString * @param filepath * / private void writeFile (inputStream inputString, String filePath) {archivo archivo = nuevo archivo (filePath); if (file.exists ()) {file.delete (); } FileOutputStream fos = null; intente {fos = new FileOutputStream (archivo); byte [] b = nuevo byte [1024]; int len; while ((len = inputString.read (b))! = -1) {fos.write (b, 0, len); } inputString.Close (); fos.close (); } Catch (FileNotFoundException e) {oyente.onfail ("FileNotFoundException"); } catch (ioException e) {oyente.onfail ("ioexception"); }}}Por supuesto, también debe prestar atención a cada ubicación de la devolución de llamada de descarga.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.