retrofit2+okhttp3下载文件
2019-01-22 本文已影响0人
邻山有木
没有加Rxjava支持,需要的自行加上即可
...别忘了请求权限
代码
Retrofit.Builder builder = new Retrofit.Builder()
.baseUrl(Utils.getBaseUrl());
//下载进度的监听器
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response orginalResponse = chain.proceed(chain.request());
return orginalResponse.newBuilder()
.body(new ProgressResponseBody(orginalResponse.body(), new ProgressListener() {
@Override
public void onProgress(long progress, long total, boolean done) {
// 计算已下载文件大小的百分比
BigDecimal totalSize = new BigDecimal(((total / 1024f) / 1024f)).setScale(2, BigDecimal.ROUND_HALF_UP);
BigDecimal progressSize = new BigDecimal(((progress / 1024f) / 1024f)).setScale(2, BigDecimal.ROUND_HALF_UP);
if (TextUtils.equals(String.valueOf(totalSize), "0.00")) {
SmartToast.show("目标文件为空文件");
return;
}
Log.d(TAG, "onProgress: 共" + totalSize + "MB,已下载" + progressSize + "MB");
if ((int) ((progress * 100) / total) > newProgress) {
newProgress = (int) ((progress * 100) / total);
Message msg = mHandler.obtainMessage();
msg.what = 100;
msg.obj = newProgress;
mHandler.sendMessage(msg);
Log.d(TAG, "onProgress: 下载百分比-->" + newProgress);
}
}
}))
.build();
}
})
.build();
//加载监听器
SystemApis download = builder.client(client).build().create(SystemApis.class);
//开始下载
download.downloadApk().enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> response) {
//下载完成,此时下载的内容还在body里面,吊桶该方法将body存到SD卡上,返回true则保存成功
try {
if (Utils.writeFileToDisk(response.body()))
mHandler.sendEmptyMessage(101);
} catch (Exception e) {
Log.e(TAG, "onResponse: ", e);
updateDialog.dismiss();
SmartToast.show("下载异常,可能服务器并未有该文件存在");
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
// 甩锅大法好
SmartToast.show("更新失败,网络异常");
}
});
这个是Handler
case 100://正在下载
int progress = (int) msg.obj;
updateDialog.setProgress(progress);
break;
case 101://下载完成
updateDialog.dismiss();
SmartToast.show("下载完成,准备安装");
Utils.installPackage(LoginActivity.this, Constant.SDCardPath.APKName);
break;
case 102://保存失败(或者下载失败)
updateDialog.dismiss();
SmartToast.show("遇到未知错误,请重新下载");
break;
ProcessResponseBody
import okhttp3.MediaType;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;
/**
* 重写ResponseBody,实现监听下载进度功能
* Created by danie on 2017/11/22.
*/
public class ProgressResponseBody extends ResponseBody {
private final ResponseBody responseBody;
private final ProgressListener listener;
private BufferedSource bufferedSource;
public ProgressResponseBody(ResponseBody responseBody, ProgressListener listener) {
this.responseBody = responseBody;
this.listener = listener;
}
@Nullable
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() {
return responseBody.contentLength();
}
@Override
public BufferedSource source() {
if (null == bufferedSource) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
@Override
public long read(Buffer sink, long byteCount) throws IOException {
l ong bytesRead = super.read(sink, byteCount);
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
listener.onProgress(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
return bytesRead;
}
};
}
}
ProgressListener
/**
* Retrofit下载文件时下载进度的回调
* Created by danie on 2017/11/22.
*/
public interface ProgressListener {
/**
* @param progress 已经下载或上传字节数
* @param total 总字节数
* @param done 是否完成
*/
void onProgress(long progress, long total, boolean done);
}
OJBK,现在才是真的要下班了!