Android开发 retrofit下载与上传
生活随笔
收集整理的這篇文章主要介紹了
Android开发 retrofit下载与上传
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言
此博客只講解retrofit下載與上傳的使用,其實與其說是retrofit的下載與上傳還不如說,依然是Okhttp的下載與上傳.如果你需要了解retrofit入門請查看這篇博客(此博客不在詳細講解一些基礎的東西):https://www.cnblogs.com/guanxinjing/p/11594249.html
下載
設置下載接口
public interface HttpList {
@Streaming //注解這個請求將獲取數據流,此后將不會這些獲取的請求數據保存到內存中,將交與你操作.
@GET
Call<ResponseBody> download(@Url String url);
}
這里有一個很重要的東西! @Url屬性, 這個屬性是你導入的下載地址. 它可以是絕對地址和可以是相對地址,當你使用這個屬性的時候,Retrofit設置基礎Url的baseUrl("http://p.gdown.baidu.com/") 將自動判斷地址是絕對還是相對,從而選擇拼接Url還是替換Url !
請求下載
private void downloadFile() {
final File file = new File(getExternalCacheDir(), "demo.apk");
if (file.exists()) {
file.delete();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://p.gdown.baidu.com/")//base的網絡地址
.callbackExecutor(Executors.newSingleThreadExecutor())//設置線程,如果不設置下載在讀取流的時候就會報錯
.build();
HttpList httpList = retrofit.create(HttpList.class);
Call<ResponseBody> call = httpList.download(DOWNLOAD_URL_PATH);//下載地址 太長了所以我用DOWNLOAD_URL_PATH封裝了一下,不要誤解
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
long total = response.body().contentLength();//需要下載的總大小
long current = 0;
InputStream inputStream = response.body().byteStream();
FileOutputStream fileOutputStream = new FileOutputStream(file);
byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) {
fileOutputStream.write(bytes, 0, len);
fileOutputStream.flush();
current = current + len;
Log.e(TAG, "已經下載=" + current + " 需要下載=" + total);
}
fileOutputStream.flush();
fileOutputStream.close();
inputStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
以上的下載實現的關鍵點,其實是ResponseBody,而這個其實就是okhttp的請求接口后返回的響應body. Retrofit并沒有對這個進行封裝,所以如果你了解okhttp的使用,應該是輕輕松松的.
上傳
上傳一般有好幾種情況:
不需要進度的上傳
需要進度的上傳
批量上傳
無進度的文件上傳
接口服務類
public interface HttpList {
@Multipart
@POST("test/upfile")
Call<ResponseBody> upFile(@Part MultipartBody.Part part);
}
注意這里的Body是 MultipartBody
上傳實現
/**
* 無進度上傳
*/
private void updateFile(){
final File imageFile = new File(getExternalCacheDir() + "/image/demo.jpg");
if (!imageFile.getParentFile().exists()){
imageFile.getParentFile().mkdirs();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.doclever.cn:8090/mock/5ba0c147fa08107daa8c55c2/")
.callbackExecutor(Executors.newSingleThreadExecutor())
.build();
HttpList list = retrofit.create(HttpList.class);
//
/*
* "image/jpg" 是你要上傳的文件的格式 這個格式并不是固定的,是根據你的項目使用那些何種key也有很多是使用下面這個:
* RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile);
*/
RequestBody requestFile = RequestBody.create(MediaType.parse("image/jpg"), imageFile);
//注意這里的file是對應MultipartBody上傳文件的key名稱
MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", imageFile.getName(), requestFile);
Call<ResponseBody> call = list.upFile(multipartBody);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.e(TAG, "onResponse: 上傳成功 "+response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
有進度的文件上傳
/**
* 有進度的上傳
*/
private void updateFile(){
final File imageFile = new File(getExternalCacheDir() + "/image/demo.jpg");
if (!imageFile.getParentFile().exists()){
imageFile.getParentFile().mkdirs();
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.doclever.cn:8090/mock/5ba0c147fa08107daa8c55c2/")
.callbackExecutor(Executors.newSingleThreadExecutor())
.build();
HttpList list = retrofit.create(HttpList.class);
RequestBody requestFile = new RequestBody() {
@Nullable
@Override
public MediaType contentType() {
return MediaType.parse("image/jpg");//這里返回上傳的格式 根據項目情況也可以切換成"multipart/form-data" 等等其他格式
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
RandomAccessFile randomAccessFile = new RandomAccessFile(imageFile, "rw");
long totalLength = 0;
long currentUpLength = 0;
if (totalLength == 0) {
totalLength = randomAccessFile.length();
}
byte[] bytes = new byte[2048];
int len = 0;
try {
while ((len = randomAccessFile.read(bytes)) != -1) {
sink.write(bytes, 0, len);
currentUpLength = currentUpLength + len;
Log.e(TAG, "writeTo: totalLength="+totalLength + " currentUpLength="+currentUpLength);
}
}catch (Exception e){
Log.e(TAG, "上傳中斷");
}finally {
randomAccessFile.close();//關閉流
Log.e(TAG, "流關閉");
}
}
};
MultipartBody.Part multipartBody = MultipartBody.Part.createFormData("file", imageFile.getName(), requestFile);
Call<ResponseBody> call = list.upFile(multipartBody);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
Log.e(TAG, "onResponse: 上傳成功 "+response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
批量上傳文件(無對應key的批量上傳)
接口服務類
public interface HttpList {
@Multipart
@POST("test/upfileList")
Call<ResponseBody> upFileList(@Part List<MultipartBody.Part> partList);
}
其他與單個上傳一致
批量上傳文件(有對應key的批量上傳)
接口服務類
public interface HttpList {
@Multipart
@POST("test/upfileList")
Call<ResponseBody> upFileList(@PartMap Map<String, RequestBody> map);
}
實現批量上傳
private void updateFile3(){
final File imageFile1 = new File(getExternalCacheDir() + "/image/demo_1.jpg");
final File imageFile2 = new File(getExternalCacheDir() + "/image/demo_2.jpg");
final File imageFile3 = new File(getExternalCacheDir() + "/image/demo_3.jpg");
RequestBody requestFile1 = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile1);
RequestBody requestFile2 = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile2);
RequestBody requestFile3 = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile3);
Map<String, RequestBody> map = new HashMap<>();
map.put("file1", requestFile1); //file1 就是需要上傳每個文件的key名稱
map.put("file2", requestFile2);
map.put("file3", requestFile3);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://www.doclever.cn:8090/mock/5ba0c147fa08107daa8c55c2/")
.callbackExecutor(Executors.newSingleThreadExecutor())
.build();
HttpList list = retrofit.create(HttpList.class);
Call<ResponseBody> call = list.upFileList(map);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
//上傳成功
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}
end
總結
以上是生活随笔為你收集整理的Android开发 retrofit下载与上传的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sony Z5P 刷rec、root的方
- 下一篇: 阿里云VOD(一)