最近要做一个带进度条下载文件的功能,网上看了一圈,发现好多都是基于OkHttpClient添加拦截器来实现的,个人觉得略显复杂,所以还是采用最简单的方法来实现:基于文件写入来进行进度的监听。
<强> 2.1设计监听接口强>
根据需求设计一下接口:
公共接口DownloadListener { 空白> 公共接口DownloadService { @Streaming @ get Call下载(url字符串); } >之前 跟正常接口写法基本一致,需要注意的是要添加@Streaming注解。
默认情况下,改造在处理结果前会将服务器端响应的全部读进内存。如果服务器端返回的是一个非常大的文件,则容易发生伯父。使用@Streaming的主要作用就是把实时下载的字节就立马写入磁盘,而不用把整个文件读入内存。
<强> 2.3开始网络请求强>
公开课DownloadUtil { 公共静态无效下载(字符串url,最终字符串路径,最后DownloadListener DownloadListener) { 翻新改造=new Retrofit.Builder () .baseUrl (“http://www.xxx.com”)//通过线程池获取一个线程,指定回调在子线程中运行。 .callbackExecutor (Executors.newSingleThreadExecutor ()) .build (); DownloadService服务=retrofit.create (DownloadService.class); Call电话=service.download (url); 调用。排队(新的Callback () { @Override 公共空间> 私有静态孔隙writeResponseToDisk(字符串路径,Response 反应,DownloadListener DownloadListener) {//从响应获取输入流以及总大小 writeFileFromIS(新文件(路径),response.body () .byteStream (), response.body () .contentLength (), downloadListener); } 私有静态int sBufferSize=8192;//将输入流写入文件 私有静态孔隙writeFileFromIS(文件文件、InputStream是长totalLength DownloadListener DownloadListener) {//开始下载 downloadListener.onStart ();//创建文件 如果(! file.exists ()) { 如果(! file.getParentFile () .exists ()) .mkdir file.getParentFile () (); 尝试{ file.createNewFile (); }捕捉(IOException e) { e.printStackTrace (); downloadListener。onFail (createNewFile IOException); } } OutputStream os=零; 长currentLength=0; 尝试{ 操作系统=new BufferedOutputStream(新FileOutputStream(文件); 字节数据[]=new字节(sBufferSize); int len; ((len=6?数据、0 sBufferSize)) !=1) { 操作系统。写(数据、0 len); currentLength +=兰;//计算当前下载进度 downloadListener.onProgress ((int) (100 * currentLength/totalLength)); }//下载完成,并返回保存的文件路径 downloadListener.onFinish (file.getAbsolutePath ()); }捕捉(IOException e) { e.printStackTrace (); downloadListener.onFail (IOException); 最后}{ 尝试{ is.close (); }捕捉(IOException e) { e.printStackTrace (); } 尝试{ 如果(os !=null) { os.close (); } }捕捉(IOException e) { e.printStackTrace (); } } } >之前 所以,实际就是通过监听文件的写入来实现进度的监听。
<强> 2.5使用例子
强>字符串url=" "; 字符串路径=" "; DownloadUtil。下载(url、路径、新的DownloadListener () { @Override 公共空间onStart () {//运行在子线程 } @Override 公共空间onProgress (int进展){//运行在子线程 } @Override 公共空间onFinish (String路径){//运行在子线程 } @Override 公共空间onFail errorInfo(字符串){//运行在子线程 } });注意,上面的回调都是运行在子线程中。如果需要更新UI等操作,可以使用处理程序等来进行更新。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
使用翻新下载文件并实现进度监听的示例