Android HttpUrlConnection網(wǎng)絡(luò)請求垒在、上傳進(jìn)度(分塊上傳)和下載進(jìn)度封裝

想必很多Android開發(fā)人員都在用一些很新型的網(wǎng)絡(luò)框架镰吵,但再某些需求中,第三方的網(wǎng)絡(luò)請求框架是需要修改才能實(shí)現(xiàn)(比如上傳進(jìn)度實(shí)現(xiàn))旺入,這樣導(dǎo)致不僅引入了框架兑凿,還要重寫他的方法,項(xiàng)目的體積還變大(雖然大小是KB茵瘾,但對于Android開發(fā)人員來說項(xiàng)目體積越小越好)礼华,言歸正傳我們首先建立一個(gè)Demo,建立一個(gè)類名為HttpUrlConnectionUtil工具類拗秘,先用單利模式把它改進(jìn)一下圣絮,我這邊使用的是(內(nèi)部類式)單利模式,還有其他的單利模式雕旨,大家可以去嘗試(這里我們簡單看一下HttpUrlConnection的工作流程這樣更方便開發(fā))


image.png

HttpUrlConnection網(wǎng)絡(luò)請求(get和post)

image.png

接下來扮匠,創(chuàng)建線程池來管理線程捧请,使用Handler來進(jìn)行線程這間的轉(zhuǎn)換,也可以不用Handler棒搜,但為了方便期間使用疹蛉,接下來看看代碼就知道了,這就就不過多的解釋了力麸,代碼里面都有注釋

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Message;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class HttpUrlConnectionUtil {
    private HttpUrlConnectionUtil() {

    }

    //創(chuàng)建線程池
    private ExecutorService executorService = Executors.newCachedThreadPool();
    private OnHttpUtilListener onHttpUtilListener;

    private static class Holder {
        private static HttpUrlConnectionUtil INSTANCE = new HttpUrlConnectionUtil();
    }

    public static HttpUrlConnectionUtil getInstance() {
        return Holder.INSTANCE;
    }

    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    //成功
                    onHttpUtilListener.onSuccess((String) msg.obj);
                    break;
                case 2:
                    //錯(cuò)誤
                    onHttpUtilListener.onError((String) msg.obj);
                    break;
                case 3:
                    break;
            }
        }
    };

    public void get(OnHttpUtilListener onHttpUtilListener, final String urlPath) {
        this.onHttpUtilListener = onHttpUtilListener;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                InputStream inputStream = null;
                try {
                    //獲得URL對象
                    URL url = new URL(urlPath);
                    //返回一個(gè)URLConnection對象可款,它表示到URL所引用的遠(yuǎn)程對象的連接
                    connection = (HttpURLConnection) url.openConnection();
                    // 默認(rèn)為GET
                    connection.setRequestMethod("GET");
                    //不使用緩存
                    connection.setUseCaches(false);
                    //設(shè)置超時(shí)時(shí)間
                    connection.setConnectTimeout(10000);
                    //設(shè)置讀取超時(shí)時(shí)間
                    connection.setReadTimeout(10000);
                    //設(shè)置是否從httpUrlConnection讀入,默認(rèn)情況下是true;
                    connection.setDoInput(true);
                    //很多項(xiàng)目需要傳入cookie解開注釋(自行修改)
//                    connection.setRequestProperty("Cookie", "my_cookie");
                    //相應(yīng)碼是否為200
                    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                        //獲得輸入流
                        inputStream = connection.getInputStream();
                        //包裝字節(jié)流為字符流
                        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                        StringBuilder response = new StringBuilder();
                        String line;
                        while ((line = reader.readLine()) != null) {
                            response.append(line);
                        }
                        //這塊是獲取服務(wù)器返回的cookie(自行修改)
//                        String cookie = connection.getHeaderField("set-cookie");
                        //通過handler更新UI
                        Message message = handler.obtainMessage();
                        message.obj = response.toString();
                        message.what = 1;
                        handler.sendMessage(message);
                    } else {

                        Message message = handler.obtainMessage();
                        message.obj = String.valueOf(connection.getResponseCode());
                        message.what = 2;
                        handler.sendMessage(message);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Message message = handler.obtainMessage();
                    message.obj = e.getMessage();
                    message.what = 2;
                    handler.sendMessage(message);
                } finally {
                    if (connection != null) {
                        connection.disconnect();
                    }
                    //關(guān)閉讀寫流
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        //加入線程池
        executorService.execute(runnable);
    }
    public void post(OnHttpUtilListener onHttpUtilListener, final String urlPath, final Map<String, String> params) {
        this.onHttpUtilListener = onHttpUtilListener;
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                InputStream inputStream = null;
                OutputStream outputStream = null;
                StringBuffer body = getParamString(params);
                byte[] data = body.toString().getBytes();
                try {
                    //獲得URL對象
                    URL url = new URL(urlPath);
                    //返回一個(gè)URLConnection對象克蚂,它表示到URL所引用的遠(yuǎn)程對象的連接
                    connection = (HttpURLConnection) url.openConnection();
                    // 默認(rèn)為GET
                    connection.setRequestMethod("POST");
                    //不使用緩存
                    connection.setUseCaches(false);
                    //設(shè)置超時(shí)時(shí)間
                    connection.setConnectTimeout(10000);
                    //設(shè)置讀取超時(shí)時(shí)間
                    connection.setReadTimeout(10000);
                    //設(shè)置是否從httpUrlConnection讀入闺鲸,默認(rèn)情況下是true;
                    connection.setDoInput(true);
                    //設(shè)置為true后才能寫入?yún)?shù)
                    connection.setDoOutput(true);
                    //post請求需要設(shè)置標(biāo)頭
                    connection.setRequestProperty("Connection", "Keep-Alive");
                    connection.setRequestProperty("Charset", "UTF-8");
                    //表單參數(shù)類型標(biāo)頭
                    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                    //很多項(xiàng)目需要傳入cookie解開注釋(自行修改)
//                    connection.setRequestProperty("Cookie", "my_cookie");
                    //獲取寫入流
                    outputStream=connection.getOutputStream();
                    //寫入表單參數(shù)
                    outputStream.write(data);
                    //相應(yīng)碼是否為200
                    if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                        //獲得輸入流
                        inputStream = connection.getInputStream();
                        //包裝字節(jié)流為字符流
                        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                        StringBuilder response = new StringBuilder();
                        String line;
                        while ((line = reader.readLine()) != null) {
                            response.append(line);
                        }
                        //這塊是獲取服務(wù)器返回的cookie(自行修改)
//                        String cookie = connection.getHeaderField("set-cookie");
                        //通過handler更新UI
                        Message message = handler.obtainMessage();
                        message.obj = response.toString();
                        message.what = 1;
                        handler.sendMessage(message);
                    } else {

                        Message message = handler.obtainMessage();
                        message.obj = String.valueOf(connection.getResponseCode());
                        message.what = 2;
                        handler.sendMessage(message);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Message message = handler.obtainMessage();
                    message.obj = e.getMessage();
                    message.what = 2;
                    handler.sendMessage(message);
                } finally {
                    if (connection != null) {
                        connection.disconnect();
                    }
                    //關(guān)閉讀寫流
                    if (inputStream != null) {
                        try {
                            inputStream.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        //加入線程池
        executorService.execute(runnable);
    }

    //post請求參數(shù)
    private StringBuffer getParamString(Map<String, String> params){
        StringBuffer result = new StringBuffer();
        Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, String> param = iterator.next();
            String key = param.getKey();
            String value = param.getValue();
            result.append(key).append('=').append(value);
            if (iterator.hasNext()){
                result.append('&');
            }
        }
        return result;
    }
    //回調(diào)接口
    interface OnHttpUtilListener {
        void onError(String e);

        void onSuccess(String json);
    }
}

里面還可以繼續(xù)提取封裝,這里我就不操作了埃叭,有興趣的朋友摸恍,可以進(jìn)化代碼。
接下來看看如果使用


image.png

用起來很簡單對不對游盲,也可以用泛型封裝误墓,再用第三方Gson,這樣在項(xiàng)目用起來很方便的益缎。既然簡單請求已經(jīng)上手了谜慌,那我進(jìn)階一下吧,估計(jì)下面才是大家想找到東西~~~莺奔。

HttpUrlConnection上傳進(jìn)度(分塊上傳)和下載進(jìn)度

既然說到上傳下載我們必然離不開異步欣范,這里我們就不使用Handler雖然它很強(qiáng)大也可以實(shí)現(xiàn),但我們有更方便的解決方案令哟。那就是AsyncTask用它來實(shí)現(xiàn)線程直接的調(diào)度
接下來需要?jiǎng)?chuàng)建一個(gè)類名為HttpUrlConnectionAsyncTask工具類恼琼,代碼如下

import android.os.AsyncTask;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 括號里的類型
 * 第一個(gè)代表doInBackground方法需要傳入的類型
 * 第二個(gè)代表onProgressUpdate方法需要傳入的類型
 * 第一個(gè)代表onPostExecute方法需要傳入的類型
 */
public class HttpUrlConnectionAsyncTask extends AsyncTask<Integer, Integer, String> {

    private Integer UPLOAD = 1;

    private OnHttpProgressUtilListener onHttpProgressUtilListener;
    private String urlPath;
    private String filePath;

    public void uploadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
        this.urlPath = urlPath;
        this.filePath = filePath;
        //調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
        execute(UPLOAD);
    }

    public void downloadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
        this.urlPath = urlPath;
        this.filePath = filePath;
        //調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
        execute(2);
    }

    @Override
    protected String doInBackground(Integer... integers) {
        return integers[0].equals(UPLOAD) ? upload() : download();
    }

    private String upload() {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        File file = new File(filePath);

        String result = "";
        try {
            //獲得URL對象
            URL url = new URL(urlPath);
            //返回一個(gè)URLConnection對象,它表示到URL所引用的遠(yuǎn)程對象的連接
            connection = (HttpURLConnection) url.openConnection();
            // 默認(rèn)為GET
            connection.setRequestMethod("POST");
            //不使用緩存
            connection.setUseCaches(false);
            //設(shè)置超時(shí)時(shí)間
            connection.setConnectTimeout(10000);
            //設(shè)置讀取超時(shí)時(shí)間
            connection.setReadTimeout(10000);
            //設(shè)置是否從httpUrlConnection讀入屏富,默認(rèn)情況下是true;
            connection.setDoInput(true);
            //設(shè)置為true后才能寫入?yún)?shù)
            connection.setDoOutput(true);
            //設(shè)置為true后才能寫入?yún)?shù)
            connection.setRequestProperty("Content-Type", "multipart/form-data");
            connection.setRequestProperty("Content-Length", String.valueOf(file.length()));
            outputStream = new DataOutputStream(connection.getOutputStream());
            DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file));
            int count = 0;
            // 計(jì)算上傳進(jìn)度
            Long progress = 0L;
            byte[] bufferOut = new byte[2048];
            while ((count = dataInputStream.read(bufferOut)) != -1) {
                outputStream.write(bufferOut, 0, count);
                progress += count;
                //換算進(jìn)度
                double d = (new BigDecimal(progress / (double) file.length()).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
                double d1 = d * 100;
                //傳入的值為1-100
                onProgressUpdate((int) d1);
            }
            dataInputStream.close();
            //寫入?yún)?shù)
            if (connection.getResponseCode()==HttpURLConnection.HTTP_OK){
                //獲得輸入流
                inputStream = connection.getInputStream();
                //包裝字節(jié)流為字符流
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                result=response.toString();
            }else {
                result = String.valueOf(connection.getResponseCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
            onCancelled(e.getMessage());
        } finally {
            //關(guān)閉
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }

    private String download() {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        String result = "";
        try {
            //獲得URL對象
            URL url = new URL(urlPath);
            //返回一個(gè)URLConnection對象晴竞,它表示到URL所引用的遠(yuǎn)程對象的連接
            connection = (HttpURLConnection) url.openConnection();
            //建立實(shí)際鏈接
            connection.connect();
            inputStream=connection.getInputStream();
            //獲取文件長度
            Double size = (double) connection.getContentLength();

            outputStream = new FileOutputStream(filePath);
            int count = 0;
            // 計(jì)算上傳進(jìn)度
            Long progress = 0L;
            byte[]  bytes= new byte[2048];
            while ((count=inputStream.read(bytes))!=-1){
                outputStream.write(bytes,0,count);
                //換算進(jìn)度
                double d = (new BigDecimal(progress / size).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
                double d1 = d * 100;
                //傳入的值為1-100
                onProgressUpdate((int) d1);
            }
            result = "下載成功";
        } catch (Exception e) {
            e.printStackTrace();
            onCancelled(e.getMessage());
        } finally {
            //關(guān)閉
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }


    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        onHttpProgressUtilListener.onProgress(values[0]);
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        onHttpProgressUtilListener.onSuccess(s);
    }

    @Override
    protected void onCancelled(String s) {
        super.onCancelled(s);
        onHttpProgressUtilListener.onError(s);
    }

    interface OnHttpProgressUtilListener {
        void onError(String e);

        void onProgress(Integer length);

        void onSuccess(String json);
    }
}

上傳和下載已經(jīng)分裝好了,在進(jìn)度換算中這里面需要注意狠半,因?yàn)橛肈ouble類型比較好換算進(jìn)度噩死,BigDecimal保留了兩位小數(shù),
代碼里神年,doInBackground是異步執(zhí)行的已维,onPostExecute(上傳和下載結(jié)果)和onProgressUpdate(上傳和下載進(jìn)度)它是調(diào)度到主線程了。下面我們來說說分塊上傳該怎么實(shí)現(xiàn)已日,因?yàn)樵谏蟼黜?xiàng)目中有一些大的項(xiàng)目垛耳,服務(wù)器那邊做了可以分塊上傳,這個(gè)時(shí)候Android該怎么實(shí)現(xiàn)上傳。

HttpUrlConnection分塊上傳

首先需要一個(gè)方法來處理分塊

private byte[] getBlock(Long offset, File file, int blockSize) {
        byte[] result = new byte[blockSize];
        RandomAccessFile accessFile = null;
        try {
            accessFile = new RandomAccessFile(file, "r");
            //將文件記錄指針定位到pos位置
            accessFile.seek(offset);
            int readSize = accessFile.read(result);
            if (readSize == -1) {
                return null;
            } else if (readSize == blockSize) {
                return result;
            } else {
                byte[] tmpByte = new byte[readSize];
                System.arraycopy(result, 0, tmpByte, 0, readSize);
                return tmpByte;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (accessFile != null) {
                try {
                    accessFile.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

這里參數(shù)offset記錄文件上一次讀寫的位置堂鲜,blockSize代表每塊大小栈雳,接下來咱們看看如果實(shí)現(xiàn)網(wǎng)絡(luò)請求


    private String filePath;
    private byte[] data;
    public void uploadFileBlock(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, byte[] data) {
        this.urlPath = urlPath;
        this.data = data;
        //調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
    }
private String uploadBlock() {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;

        String result = "";
        try {
            //獲得URL對象
            URL url = new URL(urlPath);
            //返回一個(gè)URLConnection對象,它表示到URL所引用的遠(yuǎn)程對象的連接
            connection = (HttpURLConnection) url.openConnection();
            // 默認(rèn)為GET
            connection.setRequestMethod("POST");
            //不使用緩存
            connection.setUseCaches(false);
            //設(shè)置超時(shí)時(shí)間
            connection.setConnectTimeout(10000);
            //設(shè)置讀取超時(shí)時(shí)間
            connection.setReadTimeout(10000);
            //設(shè)置是否從httpUrlConnection讀入泡嘴,默認(rèn)情況下是true;
            connection.setDoInput(true);
            //設(shè)置為true后才能寫入?yún)?shù)
            connection.setDoOutput(true);
            //設(shè)置為true后才能寫入?yún)?shù)
            connection.setRequestProperty("Content-Type", "multipart/form-data");
            //這里需要改動(dòng)
            connection.setRequestProperty("Content-Length", String.valueOf(data.length));
            outputStream = new DataOutputStream(connection.getOutputStream());
            //這塊需要改為ByteArrayInputStream寫入流
            ByteArrayInputStream inputStreamByte = new ByteArrayInputStream(data);
            int count = 0;
            // 計(jì)算上傳進(jìn)度
            Integer progress = 0;
            byte[] bufferOut = new byte[2048];
            while ((count = inputStreamByte.read(bufferOut)) != -1) {
                outputStream.write(bufferOut, 0, count);
                progress += count;
                onProgressUpdate(progress);
            }
            inputStreamByte.close();
            //寫入?yún)?shù)
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                //獲得輸入流
                inputStream = connection.getInputStream();
                //包裝字節(jié)流為字符流
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                result = response.toString();
            } else {
                result = String.valueOf(connection.getResponseCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
            onCancelled(e.getMessage());
        } finally {
            //關(guān)閉
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }

這里我們傳的是byte[]而不是文件路徑了甫恩,我們下面看看整個(gè)類變成什么樣了

import android.os.AsyncTask;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 括號里的類型
 * 第一個(gè)代表doInBackground方法需要傳入的類型
 * 第二個(gè)代表onProgressUpdate方法需要傳入的類型
 * 第一個(gè)代表onPostExecute方法需要傳入的類型
 */
public class HttpUrlConnectionAsyncTask extends AsyncTask<Integer, Integer, String> {

    private Integer UPLOAD = 1;
    private Integer DOWNLOAD = 2;


    private OnHttpProgressUtilListener onHttpProgressUtilListener;
    private String urlPath;
    private String filePath;
    private byte[] data;
    public void uploadFileBlock(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, byte[] data) {
        this.urlPath = urlPath;
        this.data = data;
        //調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
        execute(UPLOAD);
    }

    public void uploadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
        this.urlPath = urlPath;
        this.filePath = filePath;
        //調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
        execute(UPLOAD);
    }


    public void downloadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
        this.urlPath = urlPath;
        this.filePath = filePath;
        //調(diào)用doInBackground方法(方法里面是異步執(zhí)行)
        execute(2);
    }

    @Override
    protected String doInBackground(Integer... integers) {
        String result;
        if (integers[0].equals(UPLOAD)) {
            result = upload();
        } else if (integers[0].equals(DOWNLOAD)) {
            result = download();
        } else {
            result = uploadBlock();
        }
        return result;
    }

    private String upload() {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        File file = new File(filePath);

        String result = "";
        try {
            //獲得URL對象
            URL url = new URL(urlPath);
            //返回一個(gè)URLConnection對象逆济,它表示到URL所引用的遠(yuǎn)程對象的連接
            connection = (HttpURLConnection) url.openConnection();
            // 默認(rèn)為GET
            connection.setRequestMethod("POST");
            //不使用緩存
            connection.setUseCaches(false);
            //設(shè)置超時(shí)時(shí)間
            connection.setConnectTimeout(10000);
            //設(shè)置讀取超時(shí)時(shí)間
            connection.setReadTimeout(10000);
            //設(shè)置是否從httpUrlConnection讀入酌予,默認(rèn)情況下是true;
            connection.setDoInput(true);
            //設(shè)置為true后才能寫入?yún)?shù)
            connection.setDoOutput(true);
            //設(shè)置為true后才能寫入?yún)?shù)
            connection.setRequestProperty("Content-Type", "multipart/form-data");
            connection.setRequestProperty("Content-Length", String.valueOf(file.length()));
            outputStream = new DataOutputStream(connection.getOutputStream());
            DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file));
            int count = 0;
            // 計(jì)算上傳進(jìn)度
            Long progress = 0L;
            byte[] bufferOut = new byte[2048];
            while ((count = dataInputStream.read(bufferOut)) != -1) {
                outputStream.write(bufferOut, 0, count);
                progress += count;
                //換算進(jìn)度
                double d = (new BigDecimal(progress / (double) file.length()).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
                double d1 = d * 100;
                //傳入的值為1-100
                onProgressUpdate((int) d1);
            }
            dataInputStream.close();
            //寫入?yún)?shù)
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                //獲得輸入流
                inputStream = connection.getInputStream();
                //包裝字節(jié)流為字符流
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                result = response.toString();
            } else {
                result = String.valueOf(connection.getResponseCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
            onCancelled(e.getMessage());
        } finally {
            //關(guān)閉
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }

    private String uploadBlock() {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;

        String result = "";
        try {
            //獲得URL對象
            URL url = new URL(urlPath);
            //返回一個(gè)URLConnection對象,它表示到URL所引用的遠(yuǎn)程對象的連接
            connection = (HttpURLConnection) url.openConnection();
            // 默認(rèn)為GET
            connection.setRequestMethod("POST");
            //不使用緩存
            connection.setUseCaches(false);
            //設(shè)置超時(shí)時(shí)間
            connection.setConnectTimeout(10000);
            //設(shè)置讀取超時(shí)時(shí)間
            connection.setReadTimeout(10000);
            //設(shè)置是否從httpUrlConnection讀入奖慌,默認(rèn)情況下是true;
            connection.setDoInput(true);
            //設(shè)置為true后才能寫入?yún)?shù)
            connection.setDoOutput(true);
            //設(shè)置為true后才能寫入?yún)?shù)
            connection.setRequestProperty("Content-Type", "multipart/form-data");
            //這里需要改動(dòng)
            connection.setRequestProperty("Content-Length", String.valueOf(data.length));
            outputStream = new DataOutputStream(connection.getOutputStream());
            //這塊需要改為ByteArrayInputStream寫入流
            ByteArrayInputStream inputStreamByte = new ByteArrayInputStream(data);
            int count = 0;
            // 計(jì)算上傳進(jìn)度
            Integer progress = 0;
            byte[] bufferOut = new byte[2048];
            while ((count = inputStreamByte.read(bufferOut)) != -1) {
                outputStream.write(bufferOut, 0, count);
                progress += count;
                onProgressUpdate(progress);
            }
            inputStreamByte.close();
            //寫入?yún)?shù)
            if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                //獲得輸入流
                inputStream = connection.getInputStream();
                //包裝字節(jié)流為字符流
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder response = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    response.append(line);
                }
                result = response.toString();
            } else {
                result = String.valueOf(connection.getResponseCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
            onCancelled(e.getMessage());
        } finally {
            //關(guān)閉
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }

    private String download() {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        String result = "";
        try {
            //獲得URL對象
            URL url = new URL(urlPath);
            //返回一個(gè)URLConnection對象抛虫,它表示到URL所引用的遠(yuǎn)程對象的連接
            connection = (HttpURLConnection) url.openConnection();
            //建立實(shí)際鏈接
            connection.connect();
            inputStream = connection.getInputStream();
            //獲取文件長度
            Double size = (double) connection.getContentLength();

            outputStream = new FileOutputStream(filePath);
            int count = 0;
            // 計(jì)算上傳進(jìn)度
            Long progress = 0L;
            byte[] bytes = new byte[2048];
            while ((count = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, count);
                //換算進(jìn)度
                double d = (new BigDecimal(progress / size).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
                double d1 = d * 100;
                //傳入的值為1-100
                onProgressUpdate((int) d1);
            }
            result = "下載成功";
        } catch (Exception e) {
            e.printStackTrace();
            onCancelled(e.getMessage());
        } finally {
            //關(guān)閉
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                connection.disconnect();
            }
        }
        return result;
    }


    @Override
    protected void onProgressUpdate(Integer... values) {
        super.onProgressUpdate(values);
        onHttpProgressUtilListener.onProgress(values[0]);
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);
        onHttpProgressUtilListener.onSuccess(s);
    }

    @Override
    protected void onCancelled(String s) {
        super.onCancelled(s);
        onHttpProgressUtilListener.onError(s);
    }

    interface OnHttpProgressUtilListener {
        void onError(String e);

        void onProgress(Integer length);

        void onSuccess(String json);
    }
}

下面我們看看如果使用分塊上傳,使用分塊上傳必須服務(wù)器支持分塊上傳才可以

int chuncks=0;//流塊
    double chunckProgress=0.0;//進(jìn)度
    private void upload(){
        //每一塊大小
        int blockLength=1024*1024*2;
        File file = new File("文件路徑");
        final long fileSize=file.length();
        //當(dāng)前第幾塊
        int chunck = 0;
        //換算總共分多少塊
        if (file.length() % blockLength == 0L) {
            chuncks= (int) (file.length() / blockLength);
        } else {
            chuncks= (int) (file.length()/ blockLength + 1);
        }
        while (chunck<chuncks){
            //換算出第幾塊的byte[]
            byte[] block = getBlock((long) (chunck * blockLength), file, blockLength);
            new HttpUrlConnectionAsyncTask().uploadFileBlock(new HttpUrlConnectionAsyncTask.OnHttpProgressUtilListener() {

                @Override
                public void onError(String e) {

                }

                @Override
                public void onProgress(Integer progress) {
                    //換算進(jìn)度
                    double d = (new BigDecimal(progress / fileSize).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
                    int pro= (int) (d*100);
                    //這個(gè)就是上傳進(jìn)度简僧,已經(jīng)換算為1-100
                    Log.d(TAG, "onProgress: "+pro);
                }

                @Override
                public void onSuccess(String json) {
                    //上傳成功

                }
            },"上傳URL 需要傳入當(dāng)前塊chunck和總塊數(shù)chuncks參數(shù)建椰,需接口支持才行",block);
            chunck++;
        }
    }

這樣就上傳成功了,以后遇到上傳下載都可以這樣用岛马,但也可以選擇第三方網(wǎng)絡(luò)請求框架棉姐,各有所長

這個(gè)是項(xiàng)目地址大家可以作為參考
git :https://github.com/GuoLiangGod/HttpUrlConnectionDemo
這篇文件,希望對大家又幫助啦逆,如果遇到問題可以留言

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伞矩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子夏志,更是在濱河造成了極大的恐慌乃坤,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件沟蔑,死亡現(xiàn)場離奇詭異湿诊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瘦材,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門厅须,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人食棕,你說我怎么就攤上這事朗和。” “怎么了宣蠕?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵例隆,是天一觀的道長。 經(jīng)常有香客問我抢蚀,道長镀层,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮唱逢,結(jié)果婚禮上吴侦,老公的妹妹穿的比我還像新娘。我一直安慰自己坞古,他們只是感情好备韧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著痪枫,像睡著了一般织堂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上奶陈,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天易阳,我揣著相機(jī)與錄音,去河邊找鬼吃粒。 笑死潦俺,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的徐勃。 我是一名探鬼主播事示,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼僻肖!你這毒婦竟也來了肖爵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤檐涝,失蹤者是張志新(化名)和其女友劉穎遏匆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谁榜,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡幅聘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窃植。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片帝蒿。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖巷怜,靈堂內(nèi)的尸體忽然破棺而出葛超,到底是詐尸還是另有隱情,我是刑警寧澤延塑,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布绣张,位于F島的核電站,受9級特大地震影響关带,放射性物質(zhì)發(fā)生泄漏侥涵。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望芜飘。 院中可真熱鬧务豺,春花似錦、人聲如沸嗦明。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娶牌。三九已至奔浅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間裙戏,已是汗流浹背乘凸。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留累榜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓灵嫌,卻偏偏與公主長得像壹罚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子寿羞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容