#目录
[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) {// 文件上传发生错误。
}
};
```