请求方式如下:需要加入 @Streaming,这个返回的是一个流。
/** * 作用:访问网络,下载大文件。 * 默认情况下,Retrofit在处理结果前会将服务器端的Response全部读进内存。 * 如果服务器端返回的是一个非常大的文件,则容易oom。 * * @return */ @Streaming @GET Call<ResponseBody> getNetworkDataAsync(@Url String urlString);
下载大文件代码:
//使用Retrofit2框架下载大文件 new Thread(new Runnable() { @Override public void run() { String urlString = Constant.URL_DOWNLOAD_VIDEO; call_big = serverInterface.getNetworkDataAsync(urlString); try { Response<ResponseBody> response = call_big.execute(); InputStream is = response.body().byteStream(); String filename = urlString.substring(urlString.lastIndexOf("/") + 1); Boolean flag = SDCardHelper.saveFileToSDCardPrivateCacheDir(is, filename, mContext); if (flag) { Intent intent = new Intent(); intent.setAction("com.steven.android_retrofit2qiushi"); Bundle bundle = new Bundle(); String filePath = SDCardHelper.getSDCardPrivateCacheDir(mContext) + File.separator + filename; bundle.putString("path", filePath); intent.putExtras(bundle); sendBroadcast(intent); } } catch (IOException e) { e.printStackTrace(); } } }).start();
所使用的方法:
getNetworkDataAsync
saveFileToSDCardPrivateCacheDir()这方法一遍下载一边写入内存卡,有效的减少了oom
// 往SD卡的私有Cache目录下保存文件public static boolean saveFileToSDCardPrivateCacheDir(InputStream data, String fileName, Context context) { BufferedInputStream bis = null; BufferedOutputStream bos = null; if (isSDCardMounted()) { File file = context.getExternalCacheDir(); try { bis = new BufferedInputStream(data); bos = new BufferedOutputStream(new FileOutputStream(new File( file, fileName))); byte[] buffer = new byte[1024*8]; int c=0; while((c=bis.read(buffer))!=-1) { bos.write(buffer, 0 ,c); bos.flush(); } return true; } catch (Exception e) { e.printStackTrace(); } finally { try { if (bis != null) { bis.close(); } if (bos != null) { bos.close(); } } catch (IOException e) { e.printStackTrace(); } } } return false;}
// 获取SD卡私有Cache目录的路径 public static String getSDCardPrivateCacheDir(Context context) { return context.getExternalCacheDir().getAbsolutePath(); }下载完成后,发送广播。进行相应的操作。