標籤:分享圖片 default roi 步驟 creat ons abstract over 分享
RxJava2和Retrofit2用的越來越多,最近也在封裝一個通用的網路請求庫,其中就包括了單檔案下載的方法,所以這裡進行記錄。文末附帶Demo
由於網上很多的方法都是使用攔截器進行進度的監聽,個人覺得使用起來非常複雜和,所以取了個巧,在檔案寫入到硬碟的時候對檔案讀寫進行監聽,就解決了retrofit2下載檔案沒有進度監聽的問題。
先上封裝之後的使用代碼,使用簡單,直接回調下載之後的檔案
封裝步驟
- 1.定義介面(使用的時候傳入完整的url,@Streaming註解可用於下載大檔案)
@Streaming @GET Observable<ResponseBody> downLoadFile(@NonNull @Url String url);
public abstract class FileDownLoadObserver<T> extends DefaultObserver<T> { @Override public void onNext(T t) { onDownLoadSuccess(t); } @Override public void onError(Throwable e) { onDownLoadFail(e); } //可以重寫,具體可由子類實現 @Override public void onComplete() { } //下載成功的回調 public abstract void onDownLoadSuccess(T t); //下載失敗回調 public abstract void onDownLoadFail(Throwable throwable); //下載進度監聽 public abstract void onProgress(int progress,long total); /** * 將檔案寫入本地 * @param responseBody 請求結果全體 * @param destFileDir 目標檔案夾 * @param destFileName 目標檔案名 * @return 寫入完成的檔案 * @throws IOException IO異常 */ public File saveFile(ResponseBody responseBody, String destFileDir, String destFileName) throws IOException { InputStream is = null; byte[] buf = new byte[2048]; int len = 0; FileOutputStream fos = null; try { is = responseBody.byteStream(); final long total = responseBody.contentLength(); long sum = 0; File dir = new File(destFileDir); if (!dir.exists()) { dir.mkdirs(); } File file = new File(dir, destFileName); fos = new FileOutputStream(file); while ((len = is.read(buf)) != -1) { sum += len; fos.write(buf, 0, len); final long finalSum = sum; //這裡就是對進度的監聽回調 onProgress((int) (finalSum * 100 / total),total); } fos.flush(); return file; } finally { try { if (is != null) is.close(); } catch (IOException e) { e.printStackTrace(); } try { if (fos != null) fos.close(); } catch (IOException e) { e.printStackTrace(); } } }}
/** * 下載單檔案,該方法不支援斷點下載 * * @param url 檔案地址 * @param destDir 隱藏檔夾 * @param fileName 隱藏檔名 * @param fileDownLoadObserver 監聽回調 */ public void downloadFile(@NonNull String url, final String destDir, final String fileName, final FileDownLoadObserver<File> fileDownLoadObserver) { Retrofit retrofit = new Retrofit.Builder() .client(new OkHttpClient()) .baseUrl(BASE_API.BASE_URL) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) .build(); retrofit .create(BASE_API.class) .downLoadFile(url) .subscribeOn(Schedulers.io())//subscribeOn和ObserOn必須在io線程,如果在主線程會出錯 .observeOn(Schedulers.io()) .observeOn(Schedulers.computation())//需要 .map(new Function<ResponseBody, File>() { @Override public File apply(@NonNull ResponseBody responseBody) throws Exception { return fileDownLoadObserver.saveFile(responseBody, destDir, fileName); } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(fileDownLoadObserver); }
downloadFile("檔案下載url","目標儲存路徑","檔案名稱",new FileDownLoadObserver<File>() { @Override public void onDownLoadSuccess(File file) { } @Override public void onDownLoadFail(Throwable throwable) { } @Override public void onProgress(int progress,long total) { } });
Android RxJava2+Retrofit2單檔案下載監聽進度封裝