美文网首页程序员
Android HttpUrlConnection网络请求、上传

Android HttpUrlConnection网络请求、上传

作者: Baymax_zgl | 来源:发表于2018-07-26 09:45 被阅读617次

    想必很多Android开发人员都在用一些很新型的网络框架,但再某些需求中,第三方的网络请求框架是需要修改才能实现(比如上传进度实现),这样导致不仅引入了框架,还要重写他的方法,项目的体积还变大(虽然大小是KB,但对于Android开发人员来说项目体积越小越好),言归正传我们首先建立一个Demo,建立一个类名为HttpUrlConnectionUtil工具类,先用单利模式把它改进一下,我这边使用的是(内部类式)单利模式,还有其他的单利模式,大家可以去尝试(这里我们简单看一下HttpUrlConnection的工作流程这样更方便开发)


    image.png

    HttpUrlConnection网络请求(get和post)

    image.png

    接下来,创建线程池来管理线程,使用Handler来进行线程这间的转换,也可以不用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() {
    
        }
    
        //创建线程池
        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:
                        //错误
                        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);
                        //返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
                        connection = (HttpURLConnection) url.openConnection();
                        // 默认为GET
                        connection.setRequestMethod("GET");
                        //不使用缓存
                        connection.setUseCaches(false);
                        //设置超时时间
                        connection.setConnectTimeout(10000);
                        //设置读取超时时间
                        connection.setReadTimeout(10000);
                        //设置是否从httpUrlConnection读入,默认情况下是true;
                        connection.setDoInput(true);
                        //很多项目需要传入cookie解开注释(自行修改)
    //                    connection.setRequestProperty("Cookie", "my_cookie");
                        //相应码是否为200
                        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                            //获得输入流
                            inputStream = connection.getInputStream();
                            //包装字节流为字符流
                            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                            StringBuilder response = new StringBuilder();
                            String line;
                            while ((line = reader.readLine()) != null) {
                                response.append(line);
                            }
                            //这块是获取服务器返回的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();
                        }
                        //关闭读写流
                        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);
                        //返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
                        connection = (HttpURLConnection) url.openConnection();
                        // 默认为GET
                        connection.setRequestMethod("POST");
                        //不使用缓存
                        connection.setUseCaches(false);
                        //设置超时时间
                        connection.setConnectTimeout(10000);
                        //设置读取超时时间
                        connection.setReadTimeout(10000);
                        //设置是否从httpUrlConnection读入,默认情况下是true;
                        connection.setDoInput(true);
                        //设置为true后才能写入参数
                        connection.setDoOutput(true);
                        //post请求需要设置标头
                        connection.setRequestProperty("Connection", "Keep-Alive");
                        connection.setRequestProperty("Charset", "UTF-8");
                        //表单参数类型标头
                        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                        //很多项目需要传入cookie解开注释(自行修改)
    //                    connection.setRequestProperty("Cookie", "my_cookie");
                        //获取写入流
                        outputStream=connection.getOutputStream();
                        //写入表单参数
                        outputStream.write(data);
                        //相应码是否为200
                        if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                            //获得输入流
                            inputStream = connection.getInputStream();
                            //包装字节流为字符流
                            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                            StringBuilder response = new StringBuilder();
                            String line;
                            while ((line = reader.readLine()) != null) {
                                response.append(line);
                            }
                            //这块是获取服务器返回的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();
                        }
                        //关闭读写流
                        if (inputStream != null) {
                            try {
                                inputStream.close();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            };
            //加入线程池
            executorService.execute(runnable);
        }
    
        //post请求参数
        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;
        }
        //回调接口
        interface OnHttpUtilListener {
            void onError(String e);
    
            void onSuccess(String json);
        }
    }
    
    

    里面还可以继续提取封装,这里我就不操作了,有兴趣的朋友,可以进化代码。
    接下来看看如果使用


    image.png

    用起来很简单对不对,也可以用泛型封装,再用第三方Gson,这样在项目用起来很方便的。既然简单请求已经上手了,那我进阶一下吧,估计下面才是大家想找到东西~~~。

    HttpUrlConnection上传进度(分块上传)和下载进度

    既然说到上传下载我们必然离不开异步,这里我们就不使用Handler虽然它很强大也可以实现,但我们有更方便的解决方案。那就是AsyncTask用它来实现线程直接的调度
    接下来需要创建一个类名为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;
    
    /**
     * 括号里的类型
     * 第一个代表doInBackground方法需要传入的类型
     * 第二个代表onProgressUpdate方法需要传入的类型
     * 第一个代表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;
            //调用doInBackground方法(方法里面是异步执行)
            execute(UPLOAD);
        }
    
        public void downloadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
            this.urlPath = urlPath;
            this.filePath = filePath;
            //调用doInBackground方法(方法里面是异步执行)
            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);
                //返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
                connection = (HttpURLConnection) url.openConnection();
                // 默认为GET
                connection.setRequestMethod("POST");
                //不使用缓存
                connection.setUseCaches(false);
                //设置超时时间
                connection.setConnectTimeout(10000);
                //设置读取超时时间
                connection.setReadTimeout(10000);
                //设置是否从httpUrlConnection读入,默认情况下是true;
                connection.setDoInput(true);
                //设置为true后才能写入参数
                connection.setDoOutput(true);
                //设置为true后才能写入参数
                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;
                // 计算上传进度
                Long progress = 0L;
                byte[] bufferOut = new byte[2048];
                while ((count = dataInputStream.read(bufferOut)) != -1) {
                    outputStream.write(bufferOut, 0, count);
                    progress += count;
                    //换算进度
                    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();
                //写入参数
                if (connection.getResponseCode()==HttpURLConnection.HTTP_OK){
                    //获得输入流
                    inputStream = connection.getInputStream();
                    //包装字节流为字符流
                    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 {
                //关闭
                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);
                //返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
                connection = (HttpURLConnection) url.openConnection();
                //建立实际链接
                connection.connect();
                inputStream=connection.getInputStream();
                //获取文件长度
                Double size = (double) connection.getContentLength();
    
                outputStream = new FileOutputStream(filePath);
                int count = 0;
                // 计算上传进度
                Long progress = 0L;
                byte[]  bytes= new byte[2048];
                while ((count=inputStream.read(bytes))!=-1){
                    outputStream.write(bytes,0,count);
                    //换算进度
                    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 {
                //关闭
                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);
        }
    }
    

    上传和下载已经分装好了,在进度换算中这里面需要注意,因为用Double类型比较好换算进度,BigDecimal保留了两位小数,
    代码里,doInBackground是异步执行的,onPostExecute(上传和下载结果)和onProgressUpdate(上传和下载进度)它是调度到主线程了。下面我们来说说分块上传该怎么实现,因为在上传项目中有一些大的项目,服务器那边做了可以分块上传,这个时候Android该怎么实现上传。

    HttpUrlConnection分块上传

    首先需要一个方法来处理分块

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

    这里参数offset记录文件上一次读写的位置,blockSize代表每块大小,接下来咱们看看如果实现网络请求

    
        private String filePath;
        private byte[] data;
        public void uploadFileBlock(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, byte[] data) {
            this.urlPath = urlPath;
            this.data = data;
            //调用doInBackground方法(方法里面是异步执行)
        }
    private String uploadBlock() {
            HttpURLConnection connection = null;
            InputStream inputStream = null;
            OutputStream outputStream = null;
    
            String result = "";
            try {
                //获得URL对象
                URL url = new URL(urlPath);
                //返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
                connection = (HttpURLConnection) url.openConnection();
                // 默认为GET
                connection.setRequestMethod("POST");
                //不使用缓存
                connection.setUseCaches(false);
                //设置超时时间
                connection.setConnectTimeout(10000);
                //设置读取超时时间
                connection.setReadTimeout(10000);
                //设置是否从httpUrlConnection读入,默认情况下是true;
                connection.setDoInput(true);
                //设置为true后才能写入参数
                connection.setDoOutput(true);
                //设置为true后才能写入参数
                connection.setRequestProperty("Content-Type", "multipart/form-data");
                //这里需要改动
                connection.setRequestProperty("Content-Length", String.valueOf(data.length));
                outputStream = new DataOutputStream(connection.getOutputStream());
                //这块需要改为ByteArrayInputStream写入流
                ByteArrayInputStream inputStreamByte = new ByteArrayInputStream(data);
                int count = 0;
                // 计算上传进度
                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();
                //写入参数
                if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    //获得输入流
                    inputStream = connection.getInputStream();
                    //包装字节流为字符流
                    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 {
                //关闭
                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[]而不是文件路径了,我们下面看看整个类变成什么样了

    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;
    
    /**
     * 括号里的类型
     * 第一个代表doInBackground方法需要传入的类型
     * 第二个代表onProgressUpdate方法需要传入的类型
     * 第一个代表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;
            //调用doInBackground方法(方法里面是异步执行)
            execute(UPLOAD);
        }
    
        public void uploadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
            this.urlPath = urlPath;
            this.filePath = filePath;
            //调用doInBackground方法(方法里面是异步执行)
            execute(UPLOAD);
        }
    
    
        public void downloadFile(OnHttpProgressUtilListener onHttpProgressUtilListener, String urlPath, String filePath) {
            this.urlPath = urlPath;
            this.filePath = filePath;
            //调用doInBackground方法(方法里面是异步执行)
            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);
                //返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
                connection = (HttpURLConnection) url.openConnection();
                // 默认为GET
                connection.setRequestMethod("POST");
                //不使用缓存
                connection.setUseCaches(false);
                //设置超时时间
                connection.setConnectTimeout(10000);
                //设置读取超时时间
                connection.setReadTimeout(10000);
                //设置是否从httpUrlConnection读入,默认情况下是true;
                connection.setDoInput(true);
                //设置为true后才能写入参数
                connection.setDoOutput(true);
                //设置为true后才能写入参数
                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;
                // 计算上传进度
                Long progress = 0L;
                byte[] bufferOut = new byte[2048];
                while ((count = dataInputStream.read(bufferOut)) != -1) {
                    outputStream.write(bufferOut, 0, count);
                    progress += count;
                    //换算进度
                    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();
                //写入参数
                if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    //获得输入流
                    inputStream = connection.getInputStream();
                    //包装字节流为字符流
                    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 {
                //关闭
                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);
                //返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
                connection = (HttpURLConnection) url.openConnection();
                // 默认为GET
                connection.setRequestMethod("POST");
                //不使用缓存
                connection.setUseCaches(false);
                //设置超时时间
                connection.setConnectTimeout(10000);
                //设置读取超时时间
                connection.setReadTimeout(10000);
                //设置是否从httpUrlConnection读入,默认情况下是true;
                connection.setDoInput(true);
                //设置为true后才能写入参数
                connection.setDoOutput(true);
                //设置为true后才能写入参数
                connection.setRequestProperty("Content-Type", "multipart/form-data");
                //这里需要改动
                connection.setRequestProperty("Content-Length", String.valueOf(data.length));
                outputStream = new DataOutputStream(connection.getOutputStream());
                //这块需要改为ByteArrayInputStream写入流
                ByteArrayInputStream inputStreamByte = new ByteArrayInputStream(data);
                int count = 0;
                // 计算上传进度
                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();
                //写入参数
                if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                    //获得输入流
                    inputStream = connection.getInputStream();
                    //包装字节流为字符流
                    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 {
                //关闭
                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);
                //返回一个URLConnection对象,它表示到URL所引用的远程对象的连接
                connection = (HttpURLConnection) url.openConnection();
                //建立实际链接
                connection.connect();
                inputStream = connection.getInputStream();
                //获取文件长度
                Double size = (double) connection.getContentLength();
    
                outputStream = new FileOutputStream(filePath);
                int count = 0;
                // 计算上传进度
                Long progress = 0L;
                byte[] bytes = new byte[2048];
                while ((count = inputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, count);
                    //换算进度
                    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 {
                //关闭
                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);
        }
    }
    

    下面我们看看如果使用分块上传,使用分块上传必须服务器支持分块上传才可以

    int chuncks=0;//流块
        double chunckProgress=0.0;//进度
        private void upload(){
            //每一块大小
            int blockLength=1024*1024*2;
            File file = new File("文件路径");
            final long fileSize=file.length();
            //当前第几块
            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) {
                        //换算进度
                        double d = (new BigDecimal(progress / fileSize).setScale(2, BigDecimal.ROUND_HALF_UP)).doubleValue();
                        int pro= (int) (d*100);
                        //这个就是上传进度,已经换算为1-100
                        Log.d(TAG, "onProgress: "+pro);
                    }
    
                    @Override
                    public void onSuccess(String json) {
                        //上传成功
    
                    }
                },"上传URL 需要传入当前块chunck和总块数chuncks参数,需接口支持才行",block);
                chunck++;
            }
        }
    

    这样就上传成功了,以后遇到上传下载都可以这样用,但也可以选择第三方网络请求框架,各有所长

    这个是项目地址大家可以作为参考
    git :https://github.com/GuoLiangGod/HttpUrlConnectionDemo
    这篇文件,希望对大家又帮助,如果遇到问题可以留言

    相关文章

      网友评论

        本文标题:Android HttpUrlConnection网络请求、上传

        本文链接:https://www.haomeiwen.com/subject/icapmftx.html