目录

NoHttp提供了两种上传文件的方式,这一章介绍了模拟表单上传文件,可以传大文件、多文件,不会发生内存溢出等问题。

Request<String> request = new StringRequest(url, RequestMethod.POST)
   .add("name",  "严振杰") // 普通参数。
   .add("head", Binary...); // 文件参数。

这里要说明的是,在表单上传中NoHttp把文件都看成BinaryBinary是NoHttp的一个接口,它有如下几种默认实现:

  • FileBinary
  • InputStreamBinary
  • ByteArrayBinary
  • BitmapBinary

多个key,上传多个文件

参数描述
head非空用户头像
image1非空发布图片1
image2非空发布图片2
image3非空发布图片3

服务器要求我们每个key对应一个文件上传,这种时候我们可以像添加普通参数那样添加文件参数:

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>:

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:

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这个接口只有四个简单的方法,我们看下源码:

public interface Binary extends Cancelable {

    long getLength(); // 返回文件大小。
    
    String getFileName(); // 返回文件名称。
    
    String getMimeType(); // 返回文件MimeType。
    
    void onWriteBinary(OutputStream outputStream); // 用传入的流,写出文件。
    
}

这四个方法是不是很简单,但是我们看到没有提供统计文件上传进度的方法啊。其实进度是在onWriteBinary()中计算出来的,为了避免每一个Binary都计算,所以NoHttp提供一个BasicBinaryBasicBinary实现了Binary接口,并且已经实现好了进度计算,我们上面说的四种文件上传的类都是继承自BasicBinary

  • FileBinary
  • InputStreamBinary
  • ByteArrayBinary
  • BitmapBinary

所以如果你要自定义了上传文件的类,你可以继承BasicBinary基类,继承后值需要简单的几行代码就可以搞定一个自定义上传类,具体代码可以参考上述四个上传的类。

因为上述四种Binary都继承自BasicBinary,所以他们全都支持监听上传进度,用法如下:

注意:所有的方法都会在主线程中被回调,所以你可以直接更新UI。

...
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) {// 文件上传发生错误。
        }
    };