继续完善一个下载文件功能
首先,在我们的基础接口INetManager里新增方法
代码如下:
/**
* Created by lenovo on 2019/11/8.
* 网络请求工具类
*/
public interface INetManager {
/**
* @param url 请求网址
* @param callback 回调
* @param tag 请求的tag
*/
void get(String url, INetGetCallBack callback, Object tag);
/**
* post请求
*
* @param url
* @param headersParam head
* @param param 参数
* @param callback 回调
* @param tag 请求的tag
*/
void post(String url, Map<String, String> headersParam, Map<String, String> param, INetPostCallBack callback, Object tag);
/**
* 下载文件
*
* @param url
* @param file 下载的文件
* @param callback 回调
* @param tag tag
*/
void downFile(String url, File file, INetDownFileCallBack callback, Object tag);
/**
* 取消请求
*
* @param tag
*/
void cancel(Object tag);
}
这一次新增一个downFile功能,传入url和下载的File,新建一个下载文件的回调,最后是请求的tag
INetDownFileCallBack代码如下
/**
* Created by lenovo on 2019/11/9.
* 下载文件的返回结果
*/
public interface INetDownFileCallBack {
void success(File file);
//下载进度
void progress(int progress);
void failed(Throwable throwable);
}
这次新增了一个progress方法
顾名思义,是用来传递下载进度的
然后,就是关键的OkhttpNetManager里的功能实现了
这边也直接上代码吧
@Override
public void downFile(String url, final File file, final INetDownFileCallBack callback, Object tag) {
if (!file.exists()) {//如果文件不存在,先创建路径
file.getParentFile().mkdirs();
}
Request.Builder builder = new Request.Builder();
Request request = builder.url(url).get().tag(tag).build();
Call call = sokHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, final IOException e) {
if (call.isCanceled()) {
return;
}
//非ui线程
shandler.post(new Runnable() {
@Override
public void run() {
//ui线程
callback.failed(e);
}
});
}
@Override
public void onResponse(final Call call, Response response) throws IOException {
InputStream is = null;
OutputStream os = null;
try {
final long totalLen = response.body().contentLength();
is = response.body().byteStream();
os = new FileOutputStream(file);
byte[] buffer = new byte[8 * 1024];
long curLen = 0;
int bufferLen = 0;
while (!call.isCanceled() && (bufferLen = is.read(buffer)) != -1) {
os.write(buffer, 0, bufferLen);
os.flush();
curLen += bufferLen;
final long finalCurLen = curLen;
shandler.post(new Runnable() {
@Override
public void run() {
//传递下载进度
callback.progress((int) (finalCurLen * 1.0f / totalLen * 100));
}
});
}
if (call.isCanceled()) {
return;
}
shandler.post(new Runnable() {
@Override
public void run() {
callback.success(file);
}
});
} catch (final Throwable e) {
if (call.isCanceled()) {
return;
}
//非ui线程
shandler.post(new Runnable() {
@Override
public void run() {
//ui线程
callback.failed(e);
}
});
} finally {
if (is != null) {
is.close();
}
if (os != null) {
os.close();
}
}
}
});
}
这些功能做完后,就是具体的使用了
记得加上文件读写权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
这里就不写动态申请权限的代码了
使用方法如下:
先创建一个File文件,这就是设置你下载下来的文件位置和名称
这里默认用存储卡的根目录
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "测试文件.apk");
然后进行下载即可
INetClient.getsInstance()
.getmNetManager()
.downFile(url,file,回调,tag);
这边的回调多了一个progress方法
就是用来显示下载进度的
可以配合SeekBar等控件进行显示
下载完成后会调用success方法
最后,你也可以测试一下之前的cancle方法
开始下载后执行取消下载的请求
看下是否会停止下载
这边是没有实现断点下载的
有需要的朋友可以查阅相关资料
自己去完善这部分功能