zoukankan      html  css  js  c++  java
  • Android利用网络编程HttpClient批量上传(两)AsyncTask+HttpClient监测进展情况,并上传

    请尊重别人的劳动。转载请注明出处: 

    Android网络编程之使用HttpClient批量上传文件(二)AsyncTask+HttpClient并实现上传进度监听


     执行效果图:

    AsyncTask+HttpClient并实现上传进度监听

            我曾在《Android网络编程之使用HttpClient批量上传文件》一文中介绍过怎样通过HttpClient实现多文件上传和server的接收。在上一篇主要使用Handler+HttpClient的方式实现文件上传。

    这一篇将介绍使用AsyncTask+HttpClient实现文件上传并监听上传进度。

    监控进度实现:

    首先定义监听器接口。例如以下所看到的:

    /**
     * 进度监听器接口
     */
    public interface ProgressListener {
        public void transferred(longtransferedBytes);
    }

            实现监控进度的关键部分就在于记录已传输字节数,所以我们需重载FilterOutputStream。重写当中的关键方法,实现进度监听的功能。例如以下所看到的。本例中首先重载的是HttpEntityWrapper。顾名思义,就是将需发送的HttpEntity打包,以便计算总字节数。代码例如以下:

    package com.jph.ufh.utils;
    
    import java.io.FilterOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import org.apache.http.HttpEntity;
    import org.apache.http.entity.HttpEntityWrapper;
    
    /**
     * ProgressOutHttpEntity:输出流(OutputStream)时记录已发送字节数
     * @author JPH
     * Date:2014.11.03
     */
    public class ProgressOutHttpEntity extends HttpEntityWrapper {
    	/**进度监听对象**/
        private final ProgressListener listener;
        public ProgressOutHttpEntity(final HttpEntity entity,final ProgressListener listener) {
            super(entity);
            this.listener = listener;
        }
    
        public static class CountingOutputStream extends FilterOutputStream {
    
            private final ProgressListener listener;
            private long transferred;
    
            CountingOutputStream(final OutputStream out,
                    final ProgressListener listener) {
                super(out);
                this.listener = listener;
                this.transferred = 0;
            }
    
            @Override
            public void write(final byte[] b, final int off, final int len)
                    throws IOException {
                out.write(b, off, len);
                this.transferred += len;
                this.listener.transferred(this.transferred);
            }
    
            @Override
            public void write(final int b) throws IOException {
                out.write(b);
                this.transferred++;
                this.listener.transferred(this.transferred);
            }
    
        }
    
        @Override
        public void writeTo(final OutputStream out) throws IOException {
            this.wrappedEntity.writeTo(out instanceof CountingOutputStream ?

    out : new CountingOutputStream(out, this.listener)); } /** * 进度监听器接口 */ public interface ProgressListener { public void transferred(long transferedBytes); } }

     

    最后就是使用上述实现的类和Httpclient进行上传并显示运行进度的功能,很easy,代码例如以下,使用AsyncTask异步上传。

    /**
     * 异步AsyncTask+HttpClient上传文件,支持多文件上传,并显示上传进度
     * @author JPH
     * Date:2014.10.09
     * last modified 2014.11.03
     */
    public class UploadUtilsAsync extends AsyncTask<String, Integer, String>{
    	/**server路径**/
    	private String url;
    	/**上传的參数**/
    	private Map<String,String>paramMap;
    	/**要上传的文件**/
    	private ArrayList<File>files;
    	private long totalSize;
    	private Context context;
    	private ProgressDialog progressDialog;
    	public UploadUtilsAsync(Context context,String url,Map<String, String>paramMap,ArrayList<File>files) {
    		this.context=context;
    		this.url=url;
    		this.paramMap=paramMap;
    		this.files=files;
    	}
    
    	@Override
    	protected void onPreExecute() {//运行前的初始化
    		// TODO Auto-generated method stub
    		progressDialog=new ProgressDialog(context);
    		progressDialog.setTitle("请稍等...");			
    		progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    		progressDialog.setCancelable(true);
    		progressDialog.show();
    		super.onPreExecute();
    	}
    
    	@Override
    	protected String doInBackground(String... params) {//运行任务
    		// TODO Auto-generated method stub
    		MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    		builder.setCharset(Charset.forName(HTTP.UTF_8));//设置请求的编码格式
    		builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//设置浏览器兼容模式
    		int count=0;
    		for (File file:files) {
    //			FileBody fileBody = new FileBody(file);//把文件转换成流对象FileBody
    //			builder.addPart("file"+count, fileBody);
    			builder.addBinaryBody("file"+count, file);
    			count++;
    		}		
    		builder.addTextBody("method", paramMap.get("method"));//设置请求參数
    		builder.addTextBody("fileTypes", paramMap.get("fileTypes"));//设置请求參数
    		HttpEntity entity = builder.build();// 生成 HTTP POST 实体  	
    		totalSize = entity.getContentLength();//获取上传文件的大小
            ProgressOutHttpEntity progressHttpEntity = new ProgressOutHttpEntity(
            		entity, new ProgressListener() {
                        @Override
                        public void transferred(long transferedBytes) {
                            publishProgress((int) (100 * transferedBytes / totalSize));//更新进度
                        }
                    });
            return uploadFile(url, progressHttpEntity);
    	}
    
    	@Override
    	protected void onProgressUpdate(Integer... values) {//运行进度
    		// TODO Auto-generated method stub
    		Log.i("info", "values:"+values[0]);
    		progressDialog.setProgress((int)values[0]);//更新进度条
    		super.onProgressUpdate(values);
    	}
    
    	@Override
    	protected void onPostExecute(String result) {//运行结果
    		// TODO Auto-generated method stub
    		Log.i("info", result);
    		Toast.makeText(context, result, Toast.LENGTH_LONG).show();
    		progressDialog.dismiss();
    		super.onPostExecute(result);
    	}
    	/**
    	 * 向server上传文件
    	 * @param url
    	 * @param entity
    	 * @return
    	 */
    	public String uploadFile(String url, ProgressOutHttpEntity entity) {				
    		HttpClient httpClient=new DefaultHttpClient();// 开启一个client HTTP 请求 
            httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
            httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);// 设置连接超时时间
            HttpPost httpPost = new HttpPost(url);//创建 HTTP POST 请求  
            httpPost.setEntity(entity);
            try {
                HttpResponse httpResponse = httpClient.execute(httpPost);
                if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                    return "文件上传成功";
                }
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (ConnectTimeoutException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (httpClient != null && httpClient.getConnectionManager() != null) {
                    httpClient.getConnectionManager().shutdown();
                }
            }
            return "文件上传失败";
        }
    }

            关于server端怎样接收:能够參考:《Android网络编程之使用HttpClient批量上传文件》,我在里面已经介绍的非常清楚了。

           假设你认为这篇博文对你有帮助的话,请为这篇博文点个赞吧!也能够关注fengyuzhengfan的博客,收看很多其它精彩!http://blog.csdn.net/fengyuzhengfan/   

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    HDU 4268 multiset
    ACM-线段树
    HDU 5014 异或之和
    HDU 5012 骰子旋转(DFS)
    HDU 5011 NIM博弈
    HDU 5007 字符串匹配
    Android-Context
    Android-视图绘制
    Android-LayoutInflater
    oracle--分页过程demo1
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4620140.html
Copyright © 2011-2022 走看看