#目錄
[TOC]
NoHttp提供了兩種上傳文件的方式,這一章介紹了模擬表單上傳文件,可以傳大文件、多文件,不會發生內存溢出等問題。
```java
Request<String> request = new StringRequest(url, RequestMethod.POST)
.add("name", "嚴振杰") // 普通參數。
.add("head", Binary...); // 文件參數。
```
這里要說明的是,在表單上傳中NoHttp把文件都看成`Binary`,`Binary`是NoHttp的一個接口,它有如下幾種默認實現:
* FileBinary
* InputStreamBinary
* ByteArrayBinary
* BitmapBinary
## 多個key,上傳多個文件
|參數|值|描述|
|:----:|:----:|:----|
|head|非空|用戶頭像|
|image1|非空|發布圖片1|
|image2|非空|發布圖片2|
|image3|非空|發布圖片3|
服務器要求我們每個key對應一個文件上傳,這種時候我們可以像添加普通參數那樣添加文件參數:
```java
File file = ...
Bitmap bitmap = ...
Binary binary1 = new FileBinary(file);
Binary binary2 = new BitmapBinary(bitmap);
Request<String> request = new StringRequest(url, RequestMethod.POST);
request.add("file", binary1).add("userHead", binary2);
```
## 1個key,上傳多個文件
|參數|值|描述|
|:----:|:----:|:----|
|images|非空|用戶發布的多張圖片|
服務器要求我們1個key對應多文件上傳,這里NoHttp支持兩種做法。
第一種做法,添加`List<Binary>`:
```java
List<Binary> binaries = new Arraylist<>(); // 文件list。
binaries.add(new FileBinary(file));
binaries.add(new BitmapBinary(bitmap, "head.png"));
Request<String> request = new StringRequest(url, RequestMethod.POST)
.add("images", binaries); // 添加文件list。
```
第二種做法,添加多個相同Key的Binary:
```java
File file = ...
Bitmap bitmap = ...
Request<String> request = new StringRequest(url, RequestMethod.POST);
// 添加多個相同key的Binary。
.add("images", new FileBinary(file))
.add("images", new BitmapBinary(bitmap, "nohttp.png"));
```
## 監聽文件上傳進度
其實`Binary`這個接口只有四個簡單的方法,我們看下源碼:
```java
public interface Binary extends Cancelable {
long getLength(); // 返回文件大小。
String getFileName(); // 返回文件名稱。
String getMimeType(); // 返回文件MimeType。
void onWriteBinary(OutputStream outputStream); // 用傳入的流,寫出文件。
}
```
這四個方法是不是很簡單,但是我們看到沒有提供統計文件上傳進度的方法啊。其實進度是在`onWriteBinary()`中計算出來的,為了避免每一個`Binary`都計算,所以NoHttp提供一個`BasicBinary`,`BasicBinary`實現了`Binary`接口,并且已經實現好了進度計算,我們上面說的四種文件上傳的類都是繼承自`BasicBinary`:
* FileBinary
* InputStreamBinary
* ByteArrayBinary
* BitmapBinary
所以如果你要自定義了上傳文件的類,你可以繼承`BasicBinary`基類,繼承后值需要簡單的幾行代碼就可以搞定一個自定義上傳類,具體代碼可以參考上述四個上傳的類。
因為上述四種`Binary`都繼承自`BasicBinary`,所以他們全都支持監聽上傳進度,用法如下:
**注意:**所有的方法都會在主線程中被回調,所以你可以直接更新UI。
```java
...
FileBinary fileBinary = new FileBinary(useHeadFile)
fileBinary.setUploadListener(0, mOnUploadListener); // 設置一個上傳監聽器。
request.add("key", fileBinary);
private OnUploadListener mOnUploadListener = new OnUploadListener() {
@Override
public void onStart(int what) {// 文件開始上傳。
}
@Override
public void onCancel(int what) {// 文件的上傳被取消時。
}
@Override
public void onProgress(int what, int progress) {// 文件的上傳進度發生變化。
}
@Override
public void onFinish(int what) {// 文件上傳完成
}
@Override
public void onError(int what, Exception exception) {// 文件上傳發生錯誤。
}
};
```