package com.yutou.okhttp; import okhttp3.Headers; import okhttp3.HttpUrl; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public abstract class FileCallback implements Callback> { private static ThreadPoolExecutor executor; private final T bean; public FileCallback(T bean) { this.bean = bean; if (executor == null) { executor = new ThreadPoolExecutor(2, 4, Long.MAX_VALUE, TimeUnit.SECONDS, new ArrayBlockingQueue(100)); } } private class DownloadTask implements Runnable { private T bean; private Headers headers; private HttpUrl url; private InputStream inputStream; public DownloadTask(T bean, Headers headers, HttpUrl url, InputStream inputStream) { this.bean = bean; this.headers = headers; this.url = url; this.inputStream = inputStream; } @Override public void run() { try { System.out.println("开始下载"); File file = new File("download" + File.separator + System.currentTimeMillis() + ".flv"); onStart(bean); if (!file.exists()) { boolean mkdirs = file.getParentFile().mkdirs(); System.out.println("mkdirs = " + mkdirs); } FileOutputStream outputStream = new FileOutputStream(file); int len; long total = 0; byte[] bytes = new byte[4096]; boolean isDownload = true; long available = inputStream.available(); while ((len = inputStream.read(bytes)) != -1 && isDownload) { total += len; outputStream.write(bytes, 0, len); outputStream.flush(); isDownload = onDownload(headers, bean, total, available); } System.out.println("下载完成"); outputStream.close(); } catch (Exception e) { e.printStackTrace(); } finally { onFinish(bean); try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } public abstract void onStart(T bean); public abstract boolean onDownload(Headers headers, T bean, long len, long total); public abstract void onFinish(T bean); public abstract void onFailure(T bean, Throwable throwable); @Override public void onResponse(Call> call, Response> response) { executor.execute(new DownloadTask(bean, response.headers(), call.request().url(), response.body().getInputStream())); } @Override public void onFailure(Call> call, Throwable throwable) { onFailure(bean, throwable); call.cancel(); } }