OkHttp下载文件并带进度条
来源:互联网 发布:专业英语翻译软件 编辑:程序博客网 时间:2024/05/18 19:43
做这一行,不能太懒,不然就被淘汰!
OkHttp是比较火的网络框架,它支持同步与异步请求,支持缓存,可以拦截,更方便下载大文件与上传文件的操作。下面我们用OkHttp来下载文件并带进度条!
相关资料:
官网地址:http://square.github.io/okhttp/
github源码地址:https://github.com/square/okhttp
一、服务器端简单搭建
可以参考搭建本地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"/>
下载文件目录结构
源码下载
阅读全文
0 0
- OkHttp下载文件并带进度条
- Retrofit(二)、使用Retrofit+OkHttp下载文件并带进度条
- Android okHttp文件下载并带进度条的demo(简单工具类)
- HttpWebRequest下载文件带进度条
- 下载文件并更新进度条
- winform带进度条的文件下载
- win8 metro HttpClient下载文件-带进度条
- Android使用okhttp封装多文件批量下载 (带进度条,取消下载)
- C# Winform下载文件并显示进度条
- Winform下载文件并显示进度条
- C# Winform下载文件并显示进度条
- Android 下载文件并显示进度条
- libcurl--下载文件并实现进度条
- OkHttp文件下载并通过Interceptor实现下载进度
- OkHttp上传文件到服务器并带进度
- [Android开发] 使用okhttp下载文件(带监听)
- android 文件上传与下载(带进度条)
- OkHttp大文件下载
- JSTL标签
- 初接触SSM(Spring+Spring MVC+Mybatis)
- Java中的设计模式
- [bzoj4034][HAOI2015]树上操作
- 平面射影几何——齐次坐标
- OkHttp下载文件并带进度条
- 说说java NIO的一些个人总结
- webpack中的babel-loader
- Lua笔记--number的存储
- Linux 0.11
- 极限编程的最佳实践
- Java NIO使用及原理分析 (四)
- 官方安装文档解读SAP S4 HANA架构
- angularjs指令:transclude