您的位置:首页 > 理论基础 > 计算机网络

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

2016-10-05 12:55 1811 查看
版权声明:本文为博主原创文章,未经博主允许不得转载。

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


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

 运行效果图:



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

监控进度实现:

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

[java]
view plain
copy

print?





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



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


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

[java]
view plain
copy

print?





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);  
    }  
}  



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进行上传并显示进度的功能,非常简单,代码如下,使用AsyncTask异步上传。

[java]
view plain
copy

print?





/** 
 * 异步AsyncTask+HttpClient上传文件,支持多文件上传,并显示上传进度 
 * @author JPH 
 * Date:2014.10.09 
 * last modified 2014.11.03 
 */  
public class UploadUtilsAsync extends AsyncTask<String, Integer, String>{  
    /**服务器路径**/  
    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);  
    }  
    /** 
     * 向服务器上传文件 
     * @param url 
     * @param entity 
     * @return 
     */  
    public String uploadFile(String url, ProgressOutHttpEntity entity) {                  
        HttpClient httpClient=new DefaultHttpClient();// 开启一个客户端 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 "文件上传失败";  
    }  
}  



/**
* 异步AsyncTask+HttpClient上传文件,支持多文件上传,并显示上传进度
* @author JPH
* Date:2014.10.09
* last modified 2014.11.03
*/
public class UploadUtilsAsync extends AsyncTask<String, Integer, String>{
/**服务器路径**/
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);
}
/**
* 向服务器上传文件
* @param url
* @param entity
* @return
*/
public String uploadFile(String url, ProgressOutHttpEntity entity) {
HttpClient httpClient=new DefaultHttpClient();// 开启一个客户端 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 "文件上传失败";
}
}


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

       如果你觉得这篇博文对你有帮助的话,请为这篇博文点个赞吧!也可以关注fengyuzhengfan的博客,收看更多精彩!http://blog.csdn.net/fengyuzhengfan/ 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐