Android Volley扩展实现支持进度条的文件上传功能
volley是一个轻量级的开源网络通信框架,开源的好处就是可以自由定制自己需要的jar包。volley里网络通信时android2.3以上用的HttpUrlConnection,2.3以下用的HttpClient,我做的改动只考虑了2.3以上,不支持2.3版本以下。HttpUrlConnection默认传输数据是将数据全部写到内存中再发送到服务端,Volley就是采用默认的方式,这样在上传大文件时很容易就outofmemory,有一种解决办法是设置每次传输流的大小:
已知文件大小:connection.setFixedLengthStreamingMode(longl);
不知道文件大小:connection.setChunkedStreamingMode(1024);//建议使用
android的文件上传一般都是模拟表单,也可以直接socket传,我这里是集成了表单上传,下面是关键类:
publicclassMultipartRequestextendsRequest{ privatefinalListener mListener; privateMap headerMap; privateMap mParams; privateFormFile[]files; privateStringBOUNDARY="---------7dc05dba8f3e19"; publicMultipartRequest(Stringurl,Listener listener,Map params,FormFile[]files){ this(Method.POST,url,listener,params,files); } publicMultipartRequest(intmethod,Stringurl,Listener listener,Map params,FormFile[]files){ super(method,url,listener); mListener=listener; mParams=params; this.files=files; } @Override publicMap getHeaders()throwsAuthFailureError{ headerMap=newHashMap (); headerMap.put("Charset","UTF-8"); //Keep-Alive headerMap.put("Connection","Keep-Alive"); headerMap.put("Content-Type","multipart/form-data;boundary="+BOUNDARY); returnheaderMap; } @Override publicbyte[]getBody()throwsAuthFailureError{ //传参数 StringBuildersb=newStringBuilder(); for(Map.Entry entry:mParams.entrySet()){ //构建表单字段内容 sb.append("--"); sb.append(BOUNDARY); sb.append("\r\n"); sb.append("Content-Disposition:form-data;name=\""+entry.getKey()+"\"\r\n\r\n"); sb.append(entry.getValue()); sb.append("\r\n"); } returnsb.toString().getBytes(); } @Override publicvoidhandRequest(OutputStreamout){ DataOutputStreamdos=(DataOutputStream)out; try{ //发送文件数据 if(files!=null){ for(FormFilefile:files){ //发送文件数据 StringBuildersplit=newStringBuilder(); split.append("--"); split.append(BOUNDARY); split.append("\r\n"); split.append("Content-Disposition:form-data;name=\""+file.getParameterName()+"\";filename=\""+file.getFilname()+"\"\r\n"); split.append("Content-Type:"+file.getContentType()+"\r\n\r\n"); dos.write(split.toString().getBytes()); if(file.getInStream()!=null){ byte[]buffer=newbyte[1024]; intlen=-1; intcount=0; while((len=file.getInStream().read(buffer))!=-1){ dos.write(buffer,0,len); count+=len; if(mListener!=null){ mListener.onProgressChange(file.getFileSize(),count); } } count=0; file.getInStream().close(); }else{ dos.write(file.getData(),0,file.getData().length); } dos.write("\r\n".getBytes()); } } dos.writeBytes("--"+BOUNDARY+"--\r\n"); dos.flush(); }catch(IOExceptione){ mListener.onError(newVolleyError(e.toString())); try{ dos.close(); }catch(IOExceptione1){ e1.printStackTrace(); } } } @Override protectedResponse parseNetworkResponse(NetworkResponseresponse){ Stringparsed; try{ parsed=newString(response.data,HttpHeaderParser.parseCharset(response.headers)); }catch(UnsupportedEncodingExceptione){ parsed=newString(response.data); } returnResponse.success(parsed,HttpHeaderParser.parseCacheHeaders(response)); } @Override protectedvoiddeliverResponse(Stringresponse){ mListener.onSuccess(response); } @Override publicvoiddeliverError(VolleyErrorerror){ mListener.onError(error); } }
附上demo连接:Android实现文件上传功能
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。