Android啟動service下載失敗後stopService,重新啟動service下載出現問題
阿新 • • 發佈:2019-01-24
在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();
}
});
}