工具类 - HttpURLConnectionUtils(支持GET/POST/文件下载)

这里写自定义目录标题

介绍

  1. 关于HttpURLConnectionUtils:
    HttpURLConnectionUtils是一个工具类,简单的封装了HttpURLConnection,使得HttpURLConnection发送get和post请求变得更简单,更便捷,链式调用,一气呵成,支持返回数据监听回调, 回调函数直接运行在主线程中,不用繁琐的线程切换,能做的都帮你做了。

  2. 关于studio输出日志:
    该工具类在开发过程中,方便查看日志,getInstance方法的第二个参数就是一个tag,用于过滤当前的网络请求,便于查看,也可以使用 ------>> 过滤所有网络请求,只能看到所有网络请求的url,params,result,err等等信息。

使用


    // POST 请求      如果没有参数,setParams方法可以省略
    String url = UrlManager.RequestUrl.commonWebsUrl;
    HttpURLConnectionUtils.getInstance(mFragment.getClass().getSimpleName(), "常用网站")
            .setUrl(url)
            .post()
            .setParams("参数名", "参数值")
            .setParams("参数名", "参数值")
            .setParams("参数名", "参数值")
            .setRequestListener(new HttpURLConnectionUtils.OnHttpURLConnectionRequestListener() {
                @Override
                public void onStart() {
                    // 加载动画start
                }

                @Override
                public void onResult(String data) {
                    // 加载动画start, 回调函数运行在主线程
                    tvLog.append("\n\n" + data);
                }

                @Override
                public void onError(int errCode, String errMsg) {
                    // 加载动画start, 回调函数运行在主线程
                    tvLog.append("\n\nerrCode: " + errCode + "\nerrMsg: " + errMsg);
                }
            })
            .sendRequest();

    // GET 请求      如果没有参数,setParams方法可以省略
    HttpURLConnectionUtils.getInstance(mFragment.getClass().getSimpleName(), "常用网站")
            .setUrl(url)
            .get()
            .setParams("参数名", "参数值")
            .setParams("参数名", "参数值")
            .setParams("参数名", "参数值")
            .setRequestListener(new HttpURLConnectionUtils.OnHttpURLConnectionRequestListener() {
                @Override
                public void onStart() {
                    // 加载动画start
                }

                @Override
                public void onResult(String data) {
                    // 加载动画start, 回调函数运行在主线程
                    tvLog.append("\n\n" + data);
                }

                @Override
                public void onError(int errCode, String errMsg) {
                    // 加载动画start, 回调函数运行在主线程
                    tvLog.append("\n\nerrCode: " + errCode + "\nerrMsg: " + errMsg);
                }
            })
            .sendRequest();
            

	// 下载文件
    String url = UrlManager.RequestUrl.smartisanBtUrl;
    HttpURLConnectionUtils.getInstance(mActivity.getClass().getSimpleName(), "下载锤子便签")
        .setUrl(url)
        .setFileName("锤子便签.apk")
        .setOnDownloadListener(new HttpURLConnectionUtils.OnDownloadListener() {
            @Override
            public void onStart() {
                // 回调函数在主线程中执行
                tvTestHttpGet.setEnabled(false);
            }
    
            @Override
            public void onProgress(String fileTotalSize, int progress, String downloadSpeed) {
                // 回调函数在主线程中执行
                tvLog.setText(progress + "%");
            }
    
            @Override
            public void onFinish(File file) {
                // 回调函数在主线程中执行
                tvTestHttpGet.setEnabled(true);
            }
    
            @Override
            public void onError(String errMsg) {
                // 回调函数在主线程中执行
                tvTestHttpGet.setEnabled(true);
            }
        });

源码

    package com.geaosu.alearn.net;
    
    import android.os.Handler;
    import android.os.Looper;
    import android.text.TextUtils;
    import android.util.Log;
    
    import com.geaosu.alearn.BuildConfig;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.OutputStreamWriter;
    import java.io.UnsupportedEncodingException;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.net.URLEncoder;
    import java.nio.charset.StandardCharsets;
    import java.util.HashMap;
    import java.util.Map;
    
    /*
    =========================== 该工具类的用法 ===========================
    =========================== 该工具类的用法 ===========================
    =========================== 该工具类的用法 ===========================
    
        // GET 请求 - 如果没有参数可是省略setParams("参数名", "参数值")方法
        String url = UrlManager.RequestUrl.commonWebsUrl;
        HttpURLConnectionUtils.getInstance(mFragment.getClass().getSimpleName(), "常用网站")
            .setUrl(url)
            .get() // 该方法可以省略,默认是post请求
            .setParams("参数名", "参数值") // 如果没有参数可是省略setParams("参数名", "参数值")方法
            .setParams("参数名", "参数值")
            .setParams("参数名", "参数值")
            .setRequestListener(new HttpURLConnectionUtils.OnHttpURLConnectionRequestListener() {
                @Override
                public void onResult(String data) {
                    // 回调函数在主线程中执行
                    tvLog.append("\n\n" + data);
                }
    
                @Override
                public void onError(int errCode, String errMsg) {
                    // 回调函数在主线程中执行
                    tvLog.append("\n\nerrCode: " + errCode + "\nerrMsg: " + errMsg);
                }
            })
            .sendRequest();
    
    
        // POST 请求 - 如果没有参数可是省略setParams("参数名", "参数值")方法
        String url = UrlManager.RequestUrl.commonWebsUrl;
        HttpURLConnectionUtils.getInstance(mFragment.getClass().getSimpleName(), "常用网站")
            .setUrl(url)
            .post() // 该方法可以省略,默认是post请求
            .setParams("参数名", "参数值") // 如果没有参数可是省略setParams("参数名", "参数值")方法
            .setParams("参数名", "参数值")
            .setParams("参数名", "参数值")
            .setRequestListener(new HttpURLConnectionUtils.OnHttpURLConnectionRequestListener() {
                @Override
                public void onResult(String data) {
                    // 回调函数在主线程中执行
                    tvLog.append("\n\n" + data);
                }
    
                @Override
                public void onError(int errCode, String errMsg) {
                    // 回调函数在主线程中执行
                    tvLog.append("\n\nerrCode: " + errCode + "\nerrMsg: " + errMsg);
                }
            })
            .sendRequest();
    
    
        // 下载文件
        String url = UrlManager.RequestUrl.smartisanBtUrl;
        HttpURLConnectionUtils.getInstance(mActivity.getClass().getSimpleName(), "下载锤子便签")
            .setUrl(url)
            .setFileName("锤子便签.apk")
            .setOnDownloadListener(new HttpURLConnectionUtils.OnDownloadListener() {
                @Override
                public void onStart() {
                    // 回调函数在主线程中执行
                    tvTestHttpGet.setEnabled(false);
                }
    
                @Override
                public void onProgress(String fileTotalSize, int progress, String downloadSpeed) {
                    // 回调函数在主线程中执行
                    tvLog.setText(progress + "%");
                }
    
                @Override
                public void onFinish(File file) {
                    // 回调函数在主线程中执行
                    tvTestHttpGet.setEnabled(true);
                }
    
                @Override
                public void onError(String errMsg) {
                    // 回调函数在主线程中执行
                    tvTestHttpGet.setEnabled(true);
                }
            });
    
    
        // 上传文件
        ==================================== 上传文件 暂时没实现 ==========================================
        ==================================== 上传文件 暂时没实现 ==========================================
        ==================================== 上传文件 暂时没实现 ==========================================
    
        String url = UrlManager.RequestUrl.smartisanBtUrl;
        HttpURLConnectionUtils.getInstance(mActivity.getClass().getSimpleName(), "下载锤子便签")
            .setUrl(url)
            .setParams("", file)
            .setFileName("锤子便签.apk")
            .setOnUploadListener(new HttpURLConnectionUtils.OnUploadListener() {
                @Override
                public void onStart() {
                    // 回调函数在主线程中执行
                    tvTestHttpGet.setEnabled(false);
                }
    
                @Override
                public void onProgress(String fileTotalSize, int progress, String downloadSpeed) {
                    // 回调函数在主线程中执行
                    tvLog.setText(progress + "%");
                }
    
                @Override
                public void onFinish(File file) {
                    // 回调函数在主线程中执行
                    tvTestHttpGet.setEnabled(true);
                }
    
                @Override
                public void onError(String errMsg) {
                    // 回调函数在主线程中执行
                    tvTestHttpGet.setEnabled(true);
                }
            });
    
    
    =========================== 该工具类的用法 ===========================
    =========================== 该工具类的用法 ===========================
    =========================== 该工具类的用法 ===========================*/
    
    /**
     * HttpURLConnection 请求工具类, 支持post,get请求,支持请求回调监听(回调函数在主线程中运行)
     */
    public class HttpURLConnectionUtils {
    
        // debug开关
        private static boolean isDebug = BuildConfig.DEBUG;
    
        // 请求错误码
        public static final int ERR_CODE_JAVA = 1;              // 操作失败
        public static final int ERR_CODE_NET_WORK = 2;          // 网络连接失败
        public static final int ERR_CODE_URL = 3;               // 请求地址错误
        public static final int ERR_CODE_PARAMS = 4;            // 请求参数错误
        public static final int ERR_CODE_RESULT = 5;            // 服务器返回数据错误
        public static final int ERR_CODE_LISTENER = 6;          // 回调监听器错误
        public static final int ERR_CODE_DEBUG = 7;             // DebugMsg错误
        public static final int ERR_CODE_DEBUG_TAG = 8;         // DebugTag错误
        public static final int ERR_CODE_CLASS = 9;             // Class错误
        public static final int ERR_CODE_REQUEST_METHOD = 10;   // 请求方式错误
        public static final int ERR_CODE_URL_ENCODER = 11;      // URL编码错误
        public static final int ERR_CODE_HTTP_CONNECTION = 12;  // Http请求连接错误
        public static final int ERR_CODE_DIR_PATH = 13;         // 文件夹路径错误
        public static final int ERR_CODE_FILE_NAME = 14;        // 文件名称错误
    
        // 请求错误码信息
        public static final String ERR_MSG_JAVA = "code is err";
        public static final String ERR_MSG_NET_WORK = "Network is err";
        public static final String ERR_MSG_URL = "Request url is a null object";
        public static final String ERR_MSG_PARAMS = "Request params name is a null object";
        public static final String ERR_MSG_RESULT = "Result data is a null object";
        public static final String ERR_MSG_LISTENER = "OnHttpURLConnectionRequestListener is a null object";
        public static final String ERR_MSG_DEBUG = "getInstance()方法参数错误: Debug Msg is a null object";
        public static final String ERR_MSG_DEBUG_TAG = "Debug Tag is a null object";
        public static final String ERR_MSG_CLASS = "getInstance()方法参数错误: Current Class is a null object";
        public static final String ERR_MSG_REQUEST_METHOD = "getInstance()方法参数错误: Request type is a null object";
        public static final String ERR_MSG_URL_ENCODER = "URL Encoder err";
        public static final String ERR_MSGE_HTTP_CONNECTION = "HTTP Connection err";
        public static final String ERR_MSG_DIR_PATH = "Folder path err";
        public static final String ERR_MSG_FILE_NAME = "File Name is err";
        public static final String ERR_MSG_DOWNLOAD_LISTENER = "OnDownloadListener is a null object";
        public static final String ERR_MSG_UPLOAD_LISTENER = "OnUploadListener is a null object";
    
        // 请求方式
        public static final String REQUEST_TYPE_POST = "POST";
        public static final String REQUEST_TYPE_GET = "GET";
        private static String REQUEST_TYPE_DEFAULT = REQUEST_TYPE_POST;
    
        // debug 过滤标识
        private static String mCurrentClass;                // 作用:过滤所有你想看的网络请求
        private static final String mDebugTag = "GSLog";    // 作用:过滤所有网络请求
        private static String mDebugMsg;                    // 作用:过滤所有你想看的网络请求
    
        // 回调监听器
        private OnRequestListener mOnRequestListener;
        private OnDownloadListener mOnDownloadListener;
    
        // 全局变量
        private static HttpURLConnectionUtils mInstance;
        private String mUrl = "";
        private String mGetRequestParamsStr = "";
        private String mPostRequestParamsStr = "";
        private String mFileName;
        private final String mDefaultDriPath = "/sdcard/Download/";
        private String mDriPath = mDefaultDriPath;
        private HashMap<String, String> mParams = new HashMap<>();
    
        // 请求回调监听器
        public interface OnRequestListener {
            void onStart();
    
            void onResult(String data);
    
            void onError(int errCode, String errMsg);
        }
    
        // 请求回调监听器,所有回调函数都运行在主线程
        public interface OnDownloadListener {
            // 开始下载
            void onStart();
    
            // 正在下载
            void onProgress(String fileTotalSize, int progress, String downloadSpeed);
    
            // 下载完成
            void onFinish(File file);
    
            // 下载失败
            void onError(String errMsg);
        }
    
        // 请求回调监听器,所有回调函数都运行在主线程
        public interface OnUploadListener {
            // 开始下载
            void onStart();
    
            // 正在下载
            void onProgress(String fileTotalSize, int progress, String uploadSpeed);
    
            // 下载完成
            void onFinish(File file);
    
            // 下载失败
            void onError(String errMsg);
        }
    
        // 获取实例 - 默认POST请求
        public static HttpURLConnectionUtils getInstance(String currentClass, String debugMsg) {
            if (currentClass == null || currentClass.length() <= 0) {
                throw new NullPointerException(ERR_MSG_DEBUG);
            }
            if (debugMsg == null || debugMsg.length() <= 0) {
                throw new NullPointerException(ERR_MSG_DEBUG);
            }
            mCurrentClass = currentClass;
            mDebugMsg = debugMsg;
            REQUEST_TYPE_DEFAULT = REQUEST_TYPE_POST;
            if (mInstance == null) {
                mInstance = new HttpURLConnectionUtils();
            }
            return mInstance;
        }
    
        // 恢复默认设置
        private void restoreDefaultSet() {
            mUrl = "";
            mPostRequestParamsStr = "";
            mParams.clear();
            mFileName = "";
            REQUEST_TYPE_DEFAULT = REQUEST_TYPE_POST;
        }
    
        // 请求地址
        public HttpURLConnectionUtils setUrl(String url) {
            restoreDefaultSet();
            if (url == null || url.length() <= 0) {
                throw new NullPointerException(ERR_MSG_URL);
            }
            mUrl = url;
            return mInstance;
        }
    
        // 设置请求参数
        public HttpURLConnectionUtils setParams(String key, String value) {
            if (mParams == null) {
                mParams = new HashMap<>();
            }
            // 中文会出现乱码情况,这里需要编码
            if (true) {
                try {
                    mParams.put(key, URLEncoder.encode(value, "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                    mOnRequestListener.onError(ERR_CODE_URL_ENCODER, ERR_MSG_URL_ENCODER);
                }
            } else {
                mParams.put(key, value);
            }
            return mInstance;
        }
    
        // 拼接get请求参数
        private void addGetParams() {
            String _getRequestParamsStr = "";
            if (mParams != null && !mParams.isEmpty()) {
                for (Map.Entry<String, String> entry : mParams.entrySet()) {
                    if (_getRequestParamsStr.length() < 1) {
                        _getRequestParamsStr = "?" + entry.getKey() + "=" + entry.getValue();
                    } else {
                        _getRequestParamsStr += "&" + entry.getKey() + "=" + entry.getValue();
                    }
                }
            }
            if (_getRequestParamsStr != null && _getRequestParamsStr.length() > 0) {
                mUrl = mUrl + _getRequestParamsStr;
            }
        }
    
        // 拼接Post请求参数
        private void addPostParams() {
            if (mParams != null && !mParams.isEmpty()) {
                mPostRequestParamsStr = mParams.toString();
            }
        }
    
        // 设置请求方式 - get
        public HttpURLConnectionUtils get() {
            REQUEST_TYPE_DEFAULT = REQUEST_TYPE_GET;
            return mInstance;
        }
    
        // 设置请求方式 - post
        public HttpURLConnectionUtils post() {
            REQUEST_TYPE_DEFAULT = REQUEST_TYPE_POST;
            return mInstance;
        }
    
        // 请求结果回调监听
        public HttpURLConnectionUtils setOnRequestListener(OnRequestListener listener) {
            if (listener == null) {
                throw new NullPointerException(ERR_MSG_LISTENER);
            }
            mOnRequestListener = listener;
            return mInstance;
        }
    
        // 发送请求
        public void sendRequest() {
            mOnRequestListener.onStart();
            if (REQUEST_TYPE_DEFAULT.equals(REQUEST_TYPE_GET)) {
                // GET 请求
                sendRequestGet();
            } else {
                // POST 请求
                sendRequestPost();
            }
        }
    
        // 发送GET请求
        private HttpURLConnectionUtils sendRequestGet() {
            // 拼接请求参数
            addGetParams();
    
            if (isDebug) {
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> url      : " + mUrl);
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> params   : " + mParams.toString());
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> type     : " + REQUEST_TYPE_DEFAULT);
            }
            // 判断请求地址是否正确
            if (mUrl != null && mUrl.length() > 0) {
                // 判断网络是否连接
                if (true) {
                    // 连接网络
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                URL url = new URL(mUrl);
                                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                                connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0");
                                connection.setRequestProperty("Content-Type", "plain/text; charset=UTF-8");
                                connection.setRequestMethod(REQUEST_TYPE_GET);
                                connection.connect();
                                BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
                                final String data = in.readLine();
                                in.close();
                                connection.disconnect();
                                if (data != null && data.length() > 0) {
                                    if (isDebug) {
                                        Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> result   : " + data);
                                    }
                                    ThreadUtils.runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            mOnRequestListener.onResult(data);
                                        }
                                    });
                                } else {
                                    if (isDebug) {
                                        Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : " + ERR_MSG_RESULT + ": data = " + data);
                                    }
                                    ThreadUtils.runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            mOnRequestListener.onError(ERR_CODE_RESULT, ERR_MSG_RESULT);
                                        }
                                    });
                                }
                            } catch (final Exception e) {
                                e.printStackTrace();
                                if (isDebug) {
                                    Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : " + ERR_MSGE_HTTP_CONNECTION + ": " + e.toString());
                                }
                                ThreadUtils.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        mOnRequestListener.onError(ERR_CODE_HTTP_CONNECTION, ERR_MSGE_HTTP_CONNECTION + ": " + e.toString());
                                    }
                                });
                            }
                        }
                    }).start();
                } else {
                    if (isDebug) {
                        Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : " + ERR_MSG_NET_WORK);
                    }
                    mOnRequestListener.onError(ERR_CODE_NET_WORK, ERR_MSG_NET_WORK);
                }
            } else {
                if (isDebug) {
                    Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : " + ERR_MSG_URL);
                }
                mOnRequestListener.onError(ERR_CODE_URL, ERR_MSG_URL);
            }
            return mInstance;
        }
    
        // 发送POST请求
        private HttpURLConnectionUtils sendRequestPost() {
            addPostParams();
    
            if (isDebug) {
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> url      : " + mUrl);
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> params   : " + mParams.toString());
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> type     : " + REQUEST_TYPE_DEFAULT);
            }
    
            // 判断请求地址是否正确
            if (mUrl != null && mUrl.length() > 0) {
                // 判断网络是否连接
                if (true) {
                    // 连接网络
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                URL url = new URL(mUrl);
                                HttpURLConnection urlCon = (HttpURLConnection) url.openConnection();
                                urlCon.setDoOutput(true);
                                urlCon.setDoInput(true);
                                urlCon.setUseCaches(false);
                                urlCon.setConnectTimeout(5 * 1000);
                                urlCon.setRequestMethod(REQUEST_TYPE_POST);
                                urlCon.addRequestProperty("Content-Type", "application/json");
                                urlCon.connect();
                                OutputStream os = urlCon.getOutputStream();
                                OutputStreamWriter osw = new OutputStreamWriter(os, StandardCharsets.UTF_8);
                                osw.write(mPostRequestParamsStr);
                                osw.flush();
                                InputStream is = urlCon.getInputStream();
                                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                                final String data = br.readLine();
                                if (data != null && data.length() > 0) {
                                    if (isDebug) {
                                        Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> result   : " + data);
                                    }
                                    ThreadUtils.runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            mOnRequestListener.onResult(data);
                                        }
                                    });
                                } else {
                                    if (isDebug) {
                                        Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : " + ERR_MSG_RESULT + ": data = " + data);
                                    }
                                    ThreadUtils.runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            mOnRequestListener.onError(ERR_CODE_RESULT, ERR_MSG_RESULT);
                                        }
                                    });
                                }
                            } catch (final Exception e) {
                                if (isDebug) {
                                    Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : " + ERR_MSGE_HTTP_CONNECTION + ": " + e.toString());
                                }
                                ThreadUtils.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        mOnRequestListener.onError(ERR_CODE_HTTP_CONNECTION, ERR_MSGE_HTTP_CONNECTION + ": " + e.toString());
                                    }
                                });
                            }
                        }
                    }).start();
                } else {
                    if (isDebug) {
                        Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : " + ERR_MSG_NET_WORK);
                    }
                    mOnRequestListener.onError(ERR_CODE_NET_WORK, ERR_MSG_NET_WORK);
                }
            } else {
                if (isDebug) {
                    Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : " + ERR_MSG_URL);
                }
                mOnRequestListener.onError(ERR_CODE_URL, ERR_MSG_URL);
            }
            return mInstance;
        }
    
        // 上传文件
        public void uploadFile(OnUploadListener listener) {
            if (isDebug) {
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> url      : " + mUrl);
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> params   : " + mParams.toString());
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> driPath  : " + mDriPath);
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> fileName : " + mFileName);
            }
    
            if (TextUtils.isEmpty(mUrl)) {
                listener.onError(ERR_MSG_URL);
                return;
            }
            if (TextUtils.isEmpty(mDriPath)) {
                listener.onError(ERR_MSG_DIR_PATH);
                return;
            }
            if (TextUtils.isEmpty(mFileName)) {
                listener.onError(ERR_MSG_FILE_NAME);
                return;
            }
    
            // 判断网络是否连接
            if (true) {
                // 连接网络
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        // your code
                    }
                }).start();
            } else {
                if (isDebug) {
                }
                listener.onError(ERR_MSG_NET_WORK);
            }
        }
    
        // 下载文件
        public void downloadFile(OnDownloadListener listener) {
            if (isDebug) {
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> url      : " + mUrl);
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> params   : " + mParams.toString());
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> driPath  : " + mDriPath);
                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> fileName : " + mFileName);
            }
    
            if (TextUtils.isEmpty(mUrl)) {
                listener.onError(ERR_MSG_URL);
                return;
            }
            if (TextUtils.isEmpty(mDriPath)) {
                listener.onError(ERR_MSG_DIR_PATH);
                return;
            }
            if (TextUtils.isEmpty(mFileName)) {
                listener.onError(ERR_MSG_FILE_NAME);
                return;
            }
    
            // 判断网络是否连接
            if (true) {
                // 连接网络
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        ThreadUtils.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (isDebug) {
                                    Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> start    : 开始下载");
                                }
                                listener.onStart();
                            }
                        });
    
                        // 下载准备
                        int downloadedSize = 0;        // 已经下载的文件大小
                        int fileTotalSize = 0;         // 文件总大小
                        // 文件夹准备
                        File file = new File(mDriPath);
                        if (!file.exists()) {           // 判断文件夹是否存在
                            if (!file.mkdirs()) {       // 文件夹不存在, 创建
                                ThreadUtils.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (isDebug) {
                                            Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : 无法创建文件夹");
                                        }
                                        listener.onError("无法创建文件夹");
                                    }
                                });
                                return;
                            }
                        }
                        // 文件全路径 = 文件夹+文件名+后缀
                        file = new File(mDriPath + File.separator + mFileName);
                        if (file == null) {
                            ThreadUtils.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    if (isDebug) {
                                        Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : 无法创建文件");
                                    }
                                    listener.onError("无法创建文件");
                                }
                            });
                            return;
                        }
                        // 流和链接
                        InputStream inputStream = null;
                        FileOutputStream outputStream = null;
                        HttpURLConnection connection = null;
                        try {
                            URL url = new URL(mUrl);
                            connection = (HttpURLConnection) url.openConnection();
                            connection.setConnectTimeout(10 * 1000);
                            connection.setReadTimeout(10 * 1000);
                            connection.connect();
                            // 获取要下载的文件信息
                            fileTotalSize = connection.getContentLength();          // 文件总大小
                            inputStream = connection.getInputStream();
                            outputStream = new FileOutputStream(file);
                            byte[] buffer = new byte[1024 * 8];
                            int len;
                            long startTime = System.currentTimeMillis(); // 开始下载时获取开始时间
                            while ((len = inputStream.read(buffer)) > 0) {
                                outputStream.write(buffer, 0, len);
                                downloadedSize += len;
    
                                long curTime = System.currentTimeMillis();
                                int usedTime = (int) ((curTime - startTime) / 1000);
                                if (usedTime == 0) usedTime = 1;
                                // int downloadSpeed = (downloadedSize / usedTime) / 1024; // 下载速度
                                int downloadSpeed = (downloadedSize / usedTime); // 下载速度
                                String printSize = HttpURLConnectionUtils.SizeUtils.getPrintSize(downloadSpeed);
    
                                // 下载速度 - 方法1
    //                        long startTime = System.currentTimeMillis(); // 开始下载时获取开始时间
    //                        long curTime = System.currentTimeMillis();
    //                        int usedTime = (int) ((curTime - startTime) / 1000);
    //                        if (usedTime == 0) usedTime = 1;
                            int downloadSpeed = (downloadedSize / usedTime) / 1024; // 下载速度
    //                        int downloadSpeed = (downloadedSize / usedTime) ; // 下载速度
    //                        String printSize = SizeUtils.getPrintSize(downloadSpeed);
    
                                // 下载速度 - 方法2 平均速度, 越往后面越稳定
    //                        long start = System.nanoTime();   //开始时间
    //                        long totalRead = 0;  //总共下载了多少
    //                        final double NANOS_PER_SECOND = 1000000000.0;  //1秒=10亿nanoseconds
    //                        final double BYTES_PER_MIB = 1024 * 1024;    //1M=1024*1024byte
    //                        while (((len = is.read(buffler, 0, 1024)) >0)) {
    //                            totalRead += len;
    //                            double speed = NANOS_PER_SECOND / BYTES_PER_MIB * totalRead / (System.nanoTime() - start + 1);
    //                        }
    
                                // 下载速度 - 方法3
                                // https://blog.csdn.net/public_calss/article/details/45534121
    
                                // 下载进度
                                final int progress = (int) (downloadedSize * 1.0f / fileTotalSize * 100);
                                String finalFileTotalSize = HttpURLConnectionUtils.SizeUtils.getPrintSize(fileTotalSize);
                                ThreadUtils.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (isDebug) {
                                            Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> download : " + progress + "%");
                                        }
                                        listener.onProgress(finalFileTotalSize, progress, printSize);
                                    }
                                });
                            }
                            // 下载成功
                            File finalFile = file;
                            ThreadUtils.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    if (isDebug) {
                                        Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> finish   : 下载完成 " + finalFile.getAbsolutePath());
                                    }
                                    listener.onFinish(finalFile);
                                }
                            });
                        } catch (Exception e) {
                            if (file.exists()) {
                                if (file.delete()) {
                                    ThreadUtils.runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            if (isDebug) {
                                                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : 下载失败, 失败信息: " + e.getMessage());
                                            }
                                            listener.onError("下载失败, 失败信息: " + e.getMessage());
                                        }
                                    });
                                } else {
                                    ThreadUtils.runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            if (isDebug) {
                                                Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : 下载失败, 失败信息: " + e.getMessage());
                                            }
                                            listener.onError("下载失败, 失败信息: " + e.getMessage());
                                        }
                                    });
                                }
                            } else {
                                ThreadUtils.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (isDebug) {
                                            Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : 下载失败, 失败信息: " + e.getMessage());
                                        }
                                        listener.onError("下载失败, 失败信息: " + e.getMessage());
                                    }
                                });
                            }
                        } finally {
                            try {
                                if (inputStream != null)
                                    inputStream.close();
                                if (outputStream != null)
                                    outputStream.close();
                                if (connection != null)
                                    connection.disconnect();
                            } catch (final Exception e) {
                                ThreadUtils.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (isDebug) {
                                            Log.d(mDebugTag, mCurrentClass + " - " + mDebugMsg + " ------>> error    : IO流关闭失败, 失败信息: " + e.getMessage());
                                        }
                                        listener.onError("IO流关闭失败, 失败信息: " + e.getMessage());
                                    }
                                });
                            }
                        }
                    }
                }).start();
            } else {
                if (isDebug) {
                }
                listener.onError(ERR_MSG_NET_WORK);
            }
        }
    
        // 设置下载文件夹
        public HttpURLConnectionUtils setDirPath(String dirPath) {
            if (dirPath == null || dirPath.length() <= 0) {
                throw new NullPointerException(ERR_MSG_DIR_PATH);
            }
            mDriPath = dirPath;
            return mInstance;
        }
    
        // 设置下载文件名称 - 注意:名称需要带上文件类型后缀,例如:锤子便签.apk     (需要带上.apk)
        public HttpURLConnectionUtils setFileName(String fileName) {
            if (fileName == null || fileName.length() <= 0) {
                throw new NullPointerException(ERR_MSG_FILE_NAME);
            }
            mFileName = fileName;
            return mInstance;
        }
    
        // 设置下载进度回调监听
        public void setOnDownloadListener(OnDownloadListener listener) {
            if (listener == null) {
                throw new NullPointerException(ERR_MSG_DOWNLOAD_LISTENER);
            }
            downloadFile(listener);
        }
    
        // 设置下载进度回调监听
        public void setOnUploadListener(OnUploadListener listener) {
            if (listener == null) {
                throw new NullPointerException(ERR_MSG_UPLOAD_LISTENER);
            }
            uploadFile(listener);
        }
    
        // 负责线程切换
        private static class ThreadUtils {
            private static Handler mHandler = new Handler(Looper.getMainLooper());
    
            // 在主线程中运行
            public static void runOnUiThread(Runnable r) {
                if (Looper.myLooper() == Looper.getMainLooper()) {
                    //主线程
                    r.run();
                } else {
                    //子线程
                    mHandler.post(r);
                }
            }
    
            // 在子线程中运行
            public static void runOnSubThread(Runnable r) {
                new Thread(r).start();
            }
    
            // 是否是主线程
            public static boolean isMainThread() {
                return Looper.getMainLooper() == Looper.myLooper();
            }
        }
    
        // 文件大小转换 - B, KB, MB, GB, TB
        private static class SizeUtils {
            public static String getPrintSize(long size) {
                //如果字节数少于1024,则直接以B为单位,否则先除于1024,后3位因太少无意义
                if (size < 1024) {
                    return String.valueOf(size) + "B";
                } else {
                    size = size / 1024;
                }
                //如果原字节数除于1024之后,少于1024,则可以直接以KB作为单位
                //因为还没有到达要使用另一个单位的时候
                //接下去以此类推
                if (size < 1024) {
                    return String.valueOf(size) + "KB";
                } else {
                    size = size / 1024;
                }
                if (size < 1024) {
                    //因为如果以MB为单位的话,要保留最后1位小数,
                    //因此,把此数乘以100之后再取余
                    size = size * 100;
                    return String.valueOf((size / 100)) + "."
                            + String.valueOf((size % 100)) + "MB";
                } else {
                    //否则如果要以GB为单位的,先除于1024再作同样的处理
                    size = size * 100 / 1024;
                    return String.valueOf((size / 100)) + "."
                            + String.valueOf((size % 100)) + "GB";
                }
            }
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值