使用service完成数据下载功能出现的问题
发布网友
发布时间:2023-03-28 20:08
我来回答
共1个回答
热心网友
时间:2023-10-29 17:52
在Android启用service后台下载,使用异步线程进行下载,下载失败时,关掉service。在重新下载时,重新启动service,启动新的异步线程进行下载;因为上一次下载失败只是启动了停止了service,但上一个异步线程任务还在继续运行,此时又有新的线程任务运行,导致两个不同的线程访问同一段代码,导致出错。解决办法是,上一次下载失败时,除了关闭service也要cancel掉异步下载任务的request。
OkHttpClient mOkHttpClient = new OkHttpClient();
// 启动异步线程访问网络
public static void enqueue(Request request, Callback responseCallback, GetCallCancelCallback callback) {
Call call = mOkHttpClient.newCall(request);
callback.getCall(call);
call.enqueue(responseCallback);
}
一下是下载接口,传入下载的URL,存储路径,以及回调。
// 下载接口
public static void download(String downloadUrl, final String distPath, final DownloadCallback callback) {
Request request = new Request.Builder().url(downloadUrl).build();
enqueue(request, new Callback() {
@Override
public void onResponse(Response response) {
if (response.isSuccessful()) {
try {
InputStream is = response.body().byteStream();
long totalSize = response.body().contentLength();
FileOutputStream fos = new FileOutputStream(distPath);
int len = 0;
long downloadSize = 0;
byte[] buffer = new byte[1024 * 8];
while ((len = is.read(buffer)) != -1) {
downloadSize += len;
callback.onDownload(downloadSize, totalSize);
fos.write(buffer, 0, len);
}
if (callback != null) {
callback.onSuccess(null);
return;
}
} catch (IOException e) {
if (callback != null) {
callback.onFail(null);
}
}
}
if (callback != null) {
callback.onFail(null);
}
}
@Override
public void onFailure(Request request, IOException arg1) {
if (callback != null) {
callback.onFail(null);
}
}
}, new GetCallCancelCallback() {
@Override
public void getCall(Call call) {
callback.onGetCall(call); //回调,取得此时的Call
}
});
}
// service中的关键代码
download(url, filePath, new NetUtils.DownloadCallback() {
@Override
public void onSuccess(String result) {
downloadFinish();
}
@Override
public void onDownload(final long downloadSize, final long totalSize) {
mHandler.post(new Runnable() {
@Override
public void run() {
EventBus.getDefault().post(new DownloadProgressEvent(downloadSize / 1024, totalSize / 1024));
}
});
}
@Override
public void onFail(String errorInfo) {
//删掉该文件
LogUtils.error("onDowloadFail", "onDowloadFail");
File file = new File(filePath);
if (file.exists()) {
file.delete();
}
downloadFinish();
}
@Override
public void onTimeout() {
downloadFinish();
}
@Override
public void onGetCall(Call call) {
setCall(call);
}
});
// 关闭service,取消线程中的下载任务
private void downloadFinish() {
mHandler.post(new Runnable() {
@Override
public void run() {
isRunning = false;
LogUtils.error("Service", mCall.toString());
if (mCall != null) {
mCall.cancel(); // 取消当前的request
}
LogUtils.error("Service", "stop");
stopSelf();
}
});