請(qǐng)求聲明
// option 1: a resource relative to your base URL
@GET("/resource/example.zip")
Call<ResponseBody> downloadFileWithFixedUrl();
// option 2: using a dynamic URL
@GET
Call<ResponseBody> downloadFileWithDynamicUrlSync(@Url String fileUrl);
如果要下載的文件是靜態(tài)資源(始終位于服務(wù)器上的同一位置)测暗,并且基本URL所引用的服務(wù)器上芥丧,您可以使用選項(xiàng)1,它看起來(lái)像一個(gè)常規(guī)的Retrofit 2請(qǐng)求聲明.
下載文件我們是使用ResponseBody作為返回類(lèi)型严蓖,這里最好不要改成其他的類(lèi)型
option2中可以輕松地將動(dòng)態(tài)值作為完整網(wǎng)址傳遞到請(qǐng)求調(diào)用冈欢。
請(qǐng)求調(diào)用
FileDownloadService downloadService = RetrofitClient.create(FileDownloadService.class);
Call<ResponseBody> call = downloadService.downloadFileWithDynamicUrlSync(fileUrl);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response.isSuccess()) {
boolean writtenToDisk = writeResponseBodyToDisk(response.body());
Log.d(TAG, "下載成功");
} else {
Log.d(TAG, "下載失敗");
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
Log.e(TAG, "error");
}
});
FileDownloadService類(lèi)是你實(shí)現(xiàn)的請(qǐng)求聲明活玲,就是上面介紹的瞒津。
RetrofitClient代碼如下:
public class JuheRetrofit extends BaseRetrofit{
private static OkHttpClient httpClient;
private static Gson gson;
private static HttpLoggingInterceptor logging;
private static Retrofit retrofit;
/**
* 獲取接口ApiService
*
* @return
*/
public static JuheApiService getJuheApiService() {
return getRetrofit().create(JuheApiService.class);
}
/**
* 指定Gons格式
*
* @return
*/
protected static Gson getGson() {
if (gson == null) {
gson = new GsonBuilder()
.setLenient()
.setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ")
.create();
}
return gson;
}
/**
* 設(shè)置HttpClient設(shè)置
*
* @return
*/
protected static OkHttpClient getOkHttpClient() {
if (httpClient == null) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
if (BuildConfig.DEBUG) {
builder.addInterceptor(getHttpLoggingInterceptor());
}
builder.connectTimeout(20, TimeUnit.SECONDS);
httpClient = builder.build();
}
return httpClient;
}
/**
* Log信息攔截器
*
* @return
*/
protected static Interceptor getHttpLoggingInterceptor() {
if (logging == null) {
logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
}
return logging;
}
/**
* 獲取Retrofit
*
* @return
*/
private static Retrofit getRetrofit() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(UrlConstant.BASE_JUHE)
.client(getOkHttpClient())
.addConverterFactory(GsonConverterFactory.create(getGson()))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
return retrofit;
}
}
定義了聲明文件潮饱,也是現(xiàn)實(shí)請(qǐng)求調(diào)用来氧,最后就要處理ResponseBody數(shù)據(jù)了,上面我們通過(guò)writeFileToSDCard()方法將文件保存到手機(jī)SDCard中
數(shù)據(jù)保存
private boolean writeFileToSDCard(ResponseBody body) {
try {
// todo change the file location/name according to your needs
File futureStudioIconFile = new File(getExternalFilesDir(null) + File.separator + "Future Studio Icon.png");
InputStream inputStream = null;
OutputStream outputStream = null;
try {
byte[] fileReader = new byte[4096];
long fileSize = body.contentLength();
long fileSizeDownloaded = 0;
inputStream = body.byteStream();
outputStream = new FileOutputStream(futureStudioIconFile);
while (true) {
int read = inputStream.read(fileReader);
if (read == -1) {
break;
}
outputStream.write(fileReader, 0, read);
fileSizeDownloaded += read;
Log.d(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
}
outputStream.flush();
return true;
} catch (IOException e) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
return false;
}
}
有一個(gè)問(wèn)題:在默認(rèn)情況下,Retrofit在處理結(jié)果之前將整個(gè)服務(wù)器響應(yīng)放入內(nèi)存,這適用于一些JSON或XML響應(yīng)啦扬,但大文件可以輕松導(dǎo)致內(nèi)存不足錯(cuò)誤
所以如果你下載的是大文件中狂,你需要使用@Streaming注解,如下:
@Streaming
@GET
Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);
注意扑毡,如果你使用了@Streaming胃榕,不要忘了把上面的writeFileToSDCard()方法放在異步線程中,否則可能會(huì)拋出android.os.NetworkOnMainThreadException異常瞄摊。
以上就是Retrofit文件下載的所有內(nèi)容了勋又,如果不清楚了可以互相交流