android中实现OkHttp下载文件并带进度条
程序员文章站
2022-05-28 10:14:35
okhttp是比较火的网络框架,它支持同步与异步请求,支持缓存,可以拦截,更方便下载大文件与上传文件的操作。下面我们用okhttp来下载文件并带进度条!
相关资料:...
okhttp是比较火的网络框架,它支持同步与异步请求,支持缓存,可以拦截,更方便下载大文件与上传文件的操作。下面我们用okhttp来下载文件并带进度条!
相关资料:
官网地址:
github源码地址:
一、服务器端简单搭建
可以参考搭建本地tomcat服务器及相关配置 这篇文章。
新建项目okhttpserver,在webcontent目录下新建downloadfile目录,将要下载的jpg文件放在项目下。如下图:
启动服务器,文件下载地址为http://localhost:8080/okhttpserver/download/2.jpg 。这样我们服务器就搭好了。
二、android端
下面我们进入正题。
1.build.gradle的dependencies配置如下
compile 'com.android.support:appcompat-v7:24.1.1' compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.squareup.okio:okio:1.7.0'
2.activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingbottom="@dimen/activity_vertical_margin" android:paddingleft="@dimen/activity_horizontal_margin" android:paddingright="@dimen/activity_horizontal_margin" android:paddingtop="@dimen/activity_vertical_margin" tools:context="com.huang.myokhttp.mainactivity"> <button android:id="@+id/ok_download" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="下载文件" /> <textview android:id="@+id/download_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="0" /> <progressbar android:id="@+id/download_progress" style="?android:attr/progressbarstylehorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" /> </relativelayout>
3.编写okhttputil如下:
private static okhttpclient okhttpclient = new okhttpclient.builder().connecttimeout(10000, timeunit.milliseconds) .readtimeout(10000,timeunit.milliseconds) .writetimeout(10000,timeunit.milliseconds).build(); //下载文件方法 public static void downloadfile(string url, final progresslistener listener, callback callback){ //增加拦截器 okhttpclient client = okhttpclient.newbuilder().addnetworkinterceptor(new interceptor() { @override public response intercept(chain chain) throws ioexception { response response = chain.proceed(chain.request()); return response.newbuilder().body(new progressresponsebody(response.body(),listener)).build(); } }).build(); request request = new request.builder().url(url).build(); client.newcall(request).enqueue(callback); }
4.上面代码中的progressresponsebody是自己编写的类,progresslistener 是监听的接口:
progresslistener 接口
public interface progresslistener { //已完成的 总的文件长度 是否完成 void onprogress(long currentbytes, long contentlength, boolean done); }
progressresponsebody继承responsebody ,返回监听进度
public class progressresponsebody extends responsebody { public static final int update = 0x01; public static final string tag = progressresponsebody.class.getname(); private responsebody responsebody; private progresslistener mlistener; private bufferedsource bufferedsource; private handler myhandler; public progressresponsebody(responsebody body, progresslistener listener) { responsebody = body; mlistener = listener; if (myhandler==null){ myhandler = new myhandler(); } } /** * 将进度放到主线程中显示 */ class myhandler extends handler { public myhandler() { super(looper.getmainlooper()); } @override public void handlemessage(message msg) { switch (msg.what){ case update: progressmodel progressmodel = (progressmodel) msg.obj; //接口返回 if (mlistener!=null)mlistener.onprogress(progressmodel.getcurrentbytes(),progressmodel.getcontentlength(),progressmodel.isdone()); break; } } } @override public mediatype contenttype() { return responsebody.contenttype(); } @override public long contentlength() { return responsebody.contentlength(); } @override public bufferedsource source() { if (bufferedsource==null){ bufferedsource = okio.buffer(mysource(responsebody.source())); } return bufferedsource; } private source mysource(source source) { return new forwardingsource(source) { long totalbytesread = 0l; @override public long read(buffer sink, long bytecount) throws ioexception { long bytesread = super.read(sink, bytecount); totalbytesread +=bytesread!=-1?bytesread:0; //发送消息到主线程,progressmodel为自定义实体类 message msg = message.obtain(); msg.what = update; msg.obj = new progressmodel(totalbytesread,contentlength(),totalbytesread==contentlength()); myhandler.sendmessage(msg); return bytesread; } }; } }
5.mainactivity的代码:
public class mainactivity extends appcompatactivity implements view.onclicklistener{ public static final string tag = mainactivity.class.getname(); private progressbar download_progress; private textview download_text; public static string basepath = environment.getexternalstoragedirectory().getabsolutepath() + "/okhttp"; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); download_progress = (progressbar) findviewbyid(r.id.download_progress); download_text = (textview) findviewbyid(r.id.download_text); findviewbyid(r.id.ok_download).setonclicklistener(this); } @override public void onclick(view view) { switch (view.getid()){ case r.id.ok_download: string url = "http://192.168.0.104:8080/okhttpserver/download/2.jpg"; final string filename = url.split("/")[url.split("/").length - 1]; log.i(tag, "filename==" + filename); okhttputil.downloadfile(url, new progresslistener() { @override public void onprogress(long currentbytes, long contentlength, boolean done) { log.i(tag, "currentbytes==" + currentbytes + "==contentlength==" + contentlength + "==done==" + done); int progress = (int) (currentbytes * 100 / contentlength); download_progress.setprogress(progress); download_text.settext(progress + "%"); } }, new callback() { @override public void onfailure(call call, ioexception e) { } @override public void onresponse(call call, response response) throws ioexception { if (response != null) { inputstream is = response.body().bytestream(); fileoutputstream fos = new fileoutputstream(new file(basepath + "/" + filename)); int len = 0; byte[] buffer = new byte[2048]; while (-1 != (len = is.read(buffer))) { fos.write(buffer, 0, len); } fos.flush(); fos.close(); is.close(); } } }); break; } } }
6.最后不要忘了添加权限:
<uses-permission android:name="android.permission.internet"/> <uses-permission android:name="android.permission.write_external_storage"/> <uses-permission android:name="android.permission.read_external_storage"/>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
Android中DownloadManager实现文件下载实例详解
-
android中实现OkHttp下载文件并带进度条
-
Android中实现OkHttp上传文件到服务器并带进度
-
Android开发中实现下载文件通知栏显示进度条
-
Winform中实现向窗体中拖放照片并显示以及拖放文件夹显示树形结构(附代码下载)
-
Android中实现下载和解压zip文件功能代码分享
-
Android使用HttpClient实现文件上传到PHP服务器,并监控进度条
-
Android中实现OkHttp上传文件到服务器并带进度
-
android中实现OkHttp下载文件并带进度条
-
Android使用HttpClient实现文件上传到PHP服务器,并监控进度条