Android網路編程之使用HttpClient批量上傳檔案(二)AsyncTask+HttpClient並實現上傳進度監聽

來源:互聯網
上載者:User

Android網路編程之使用HttpClient批量上傳檔案(二)AsyncTask+HttpClient並實現上傳進度監聽

請尊重他人的勞動成果,轉載請註明出處:

Android網路編程之使用HttpClient批量上傳檔案(二)AsyncTask+HttpClient並實現上傳進度監聽

運行:


我曾在《Android網路編程之使用HttpClient批量上傳檔案》一文中介紹過如何通過HttpClient實現多檔案上傳和伺服器的接收。在上一篇主要使用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進行上傳並顯示進度的功能,非常簡單,代碼如下,使用AsyncTask非同步上傳。

/** * 非同步AsyncTask+HttpClient上傳檔案,支援多檔案上傳,並顯示上傳進度 * @author JPH * Date:2014.10.09 * last modified 2014.11.03 */public class UploadUtilsAsync extends AsyncTask{/**伺服器路徑**/private String url;/**上傳的參數**/private MapparamMap;/**要上傳的檔案**/private ArrayListfiles;private long totalSize;private Context context;private ProgressDialog progressDialog;public UploadUtilsAsync(Context context,String url,MapparamMap,ArrayListfiles) {this.context=context;this.url=url;this.paramMap=paramMap;this.files=files;}@Overrideprotected void onPreExecute() {//執行前的初始化// TODO Auto-generated method stubprogressDialog=new ProgressDialog(context);progressDialog.setTitle("請稍等...");progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);progressDialog.setCancelable(true);progressDialog.show();super.onPreExecute();}@Overrideprotected String doInBackground(String... params) {//執行任務// TODO Auto-generated method stubMultipartEntityBuilder 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);}@Overrideprotected void onProgressUpdate(Integer... values) {//執行進度// TODO Auto-generated method stubLog.i("info", "values:"+values[0]);progressDialog.setProgress((int)values[0]);//更新進度條super.onProgressUpdate(values);}@Overrideprotected void onPostExecute(String result) {//執行結果// TODO Auto-generated method stubLog.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/

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.