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

来源:互联网 发布:万网域名不备案能用吗 编辑:程序博客网 时间:2024/05/17 00:49

请尊重他人的劳动成果,转载请注明出处: 

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


 运行效果图:

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

        我曾在《Android网络编程之使用HttpClient批量上传文件》一文中介绍过如何通过HttpClient实现多文件上传和服务器的接收。在上一篇主要使用Handler+HttpClient的方式实现文件上传。这一篇将介绍使用AsyncTask+HttpClient实现文件上传并监听上传进度。

监控进度实现:

首先定义监听器接口。如下所示:

[java] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * 进度监听器接口 
  3.  */  
  4. public interface ProgressListener {  
  5.     public void transferred(longtransferedBytes);  
  6. }  

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

[java] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. package com.jph.ufh.utils;  
  2.   
  3. import java.io.FilterOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.OutputStream;  
  6. import org.apache.http.HttpEntity;  
  7. import org.apache.http.entity.HttpEntityWrapper;  
  8.   
  9. /** 
  10.  * ProgressOutHttpEntity:输出流(OutputStream)时记录已发送字节数 
  11.  * @author JPH 
  12.  * Date:2014.11.03 
  13.  */  
  14. public class ProgressOutHttpEntity extends HttpEntityWrapper {  
  15.     /**进度监听对象**/  
  16.     private final ProgressListener listener;  
  17.     public ProgressOutHttpEntity(final HttpEntity entity,final ProgressListener listener) {  
  18.         super(entity);  
  19.         this.listener = listener;  
  20.     }  
  21.   
  22.     public static class CountingOutputStream extends FilterOutputStream {  
  23.   
  24.         private final ProgressListener listener;  
  25.         private long transferred;  
  26.   
  27.         CountingOutputStream(final OutputStream out,  
  28.                 final ProgressListener listener) {  
  29.             super(out);  
  30.             this.listener = listener;  
  31.             this.transferred = 0;  
  32.         }  
  33.   
  34.         @Override  
  35.         public void write(final byte[] b, final int off, final int len)  
  36.                 throws IOException {  
  37.             out.write(b, off, len);  
  38.             this.transferred += len;  
  39.             this.listener.transferred(this.transferred);  
  40.         }  
  41.   
  42.         @Override  
  43.         public void write(final int b) throws IOException {  
  44.             out.write(b);  
  45.             this.transferred++;  
  46.             this.listener.transferred(this.transferred);  
  47.         }  
  48.   
  49.     }  
  50.   
  51.     @Override  
  52.     public void writeTo(final OutputStream out) throws IOException {  
  53.         this.wrappedEntity.writeTo(out instanceof CountingOutputStream ? out  
  54.                 : new CountingOutputStream(out, this.listener));  
  55.     }  
  56.     /** 
  57.      * 进度监听器接口 
  58.      */  
  59.     public interface ProgressListener {  
  60.         public void transferred(long transferedBytes);  
  61.     }  
  62. }  

 

最后就是使用上述实现的类和Httpclient进行上传并显示进度的功能,非常简单,代码如下,使用AsyncTask异步上传。

[java] view plain copy
print?在CODE上查看代码片派生到我的代码片
  1. /** 
  2.  * 异步AsyncTask+HttpClient上传文件,支持多文件上传,并显示上传进度 
  3.  * @author JPH 
  4.  * Date:2014.10.09 
  5.  * last modified 2014.11.03 
  6.  */  
  7. public class UploadUtilsAsync extends AsyncTask<String, Integer, String>{  
  8.     /**服务器路径**/  
  9.     private String url;  
  10.     /**上传的参数**/  
  11.     private Map<String,String>paramMap;  
  12.     /**要上传的文件**/  
  13.     private ArrayList<File>files;  
  14.     private long totalSize;  
  15.     private Context context;  
  16.     private ProgressDialog progressDialog;  
  17.     public UploadUtilsAsync(Context context,String url,Map<String, String>paramMap,ArrayList<File>files) {  
  18.         this.context=context;  
  19.         this.url=url;  
  20.         this.paramMap=paramMap;  
  21.         this.files=files;  
  22.     }  
  23.   
  24.     @Override  
  25.     protected void onPreExecute() {//执行前的初始化  
  26.         // TODO Auto-generated method stub  
  27.         progressDialog=new ProgressDialog(context);  
  28.         progressDialog.setTitle("请稍等...");            
  29.         progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);  
  30.         progressDialog.setCancelable(true);  
  31.         progressDialog.show();  
  32.         super.onPreExecute();  
  33.     }  
  34.   
  35.     @Override  
  36.     protected String doInBackground(String... params) {//执行任务  
  37.         // TODO Auto-generated method stub  
  38.         MultipartEntityBuilder builder = MultipartEntityBuilder.create();  
  39.         builder.setCharset(Charset.forName(HTTP.UTF_8));//设置请求的编码格式  
  40.         builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);//设置浏览器兼容模式  
  41.         int count=0;  
  42.         for (File file:files) {  
  43. //          FileBody fileBody = new FileBody(file);//把文件转换成流对象FileBody  
  44. //          builder.addPart("file"+count, fileBody);  
  45.             builder.addBinaryBody("file"+count, file);  
  46.             count++;  
  47.         }         
  48.         builder.addTextBody("method", paramMap.get("method"));//设置请求参数  
  49.         builder.addTextBody("fileTypes", paramMap.get("fileTypes"));//设置请求参数  
  50.         HttpEntity entity = builder.build();// 生成 HTTP POST 实体        
  51.         totalSize = entity.getContentLength();//获取上传文件的大小  
  52.         ProgressOutHttpEntity progressHttpEntity = new ProgressOutHttpEntity(  
  53.                 entity, new ProgressListener() {  
  54.                     @Override  
  55.                     public void transferred(long transferedBytes) {  
  56.                         publishProgress((int) (100 * transferedBytes / totalSize));//更新进度  
  57.                     }  
  58.                 });  
  59.         return uploadFile(url, progressHttpEntity);  
  60.     }  
  61.   
  62.     @Override  
  63.     protected void onProgressUpdate(Integer... values) {//执行进度  
  64.         // TODO Auto-generated method stub  
  65.         Log.i("info""values:"+values[0]);  
  66.         progressDialog.setProgress((int)values[0]);//更新进度条  
  67.         super.onProgressUpdate(values);  
  68.     }  
  69.   
  70.     @Override  
  71.     protected void onPostExecute(String result) {//执行结果  
  72.         // TODO Auto-generated method stub  
  73.         Log.i("info", result);  
  74.         Toast.makeText(context, result, Toast.LENGTH_LONG).show();  
  75.         progressDialog.dismiss();  
  76.         super.onPostExecute(result);  
  77.     }  
  78.     /** 
  79.      * 向服务器上传文件 
  80.      * @param url 
  81.      * @param entity 
  82.      * @return 
  83.      */  
  84.     public String uploadFile(String url, ProgressOutHttpEntity entity) {                  
  85.         HttpClient httpClient=new DefaultHttpClient();// 开启一个客户端 HTTP 请求   
  86.         httpClient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);  
  87.         httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);// 设置连接超时时间  
  88.         HttpPost httpPost = new HttpPost(url);//创建 HTTP POST 请求    
  89.         httpPost.setEntity(entity);  
  90.         try {  
  91.             HttpResponse httpResponse = httpClient.execute(httpPost);  
  92.             if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {  
  93.                 return "文件上传成功";  
  94.             }  
  95.         } catch (ClientProtocolException e) {  
  96.             e.printStackTrace();  
  97.         } catch (ConnectTimeoutException e) {  
  98.             e.printStackTrace();  
  99.         } catch (Exception e) {  
  100.             e.printStackTrace();  
  101.         } finally {  
  102.             if (httpClient != null && httpClient.getConnectionManager() != null) {  
  103.                 httpClient.getConnectionManager().shutdown();  
  104.             }  
  105.         }  
  106.         return "文件上传失败";  
  107.     }  
  108. }  

        关于服务器端如何接收:可以参考:《Android网络编程之使用HttpClient批量上传文件》,我在里面已经介绍的很清楚了。

       如果你觉得这篇博文对你有帮助的话,请为这篇博文点个赞吧!也可以关注fengyuzhengfan的博客,收看更多精彩!http://blog.csdn.net/fengyuzhengfan/   

0 0