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