下载工具类 - 基于 HttpURLConnection

使用方法和源代码看注释

package com.geaosu.alearn;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/*

=========================== 该工具类的用法 ===========================
=========================== 该工具类的用法 ===========================
=========================== 该工具类的用法 ===========================

    // 锤子便签
    String url = "https://01911f43fa7455a7a99a61cc172fc905.dd.cdntips.com/imtt.dd.qq.com/16891/apk/15A873B930E4EDF0A772A67566516D38.apk?mkey=5f4778860e864886&f=0f1d&fsname=com.smartisan.notes_3.7.2_47.apk&csr=1bbd&cip=14.134.110.115&proto=https";

    // 调用方法一
    DownloadUtils.getInstance()
            .setUrl(url)
            .setDirPath("/sdcard/Download/")
            .setFileName("锤子便签")
            .setOnDownloadListener(new DownloadUtils.OnDownloadListener() {
                @Override
                public void onStart() {

                }

                @Override
                public void onProgress(int fileTotalSize, int progress) {

                }

                @Override
                public void onFinish(File file) {

                }

                @Override
                public void onError(String errMsg) {

                }
            });


    // 调用方法二
    DownloadUtils instance = DownloadUtils.getInstance();
    instance.downLoadFile(url, "/sdcard/Download/", "锤子便签", new DownloadUtils.OnDownloadListener() {
        @Override
        public void onStart() {

        }

        @Override
        public void onProgress(int fileTotalSize, int progress) {

        }

        @Override
        public void onFinish(File file) {

        }

        @Override
        public void onError(String errMsg) {

        }
    });


=========================== 该工具类的用法 ===========================
=========================== 该工具类的用法 ===========================
=========================== 该工具类的用法 ===========================

*/

/**
 * 下载工具
 */
public class DownloadUtils {
    private static final String TAG = "DownloadUtils";
    private static Context mContext;
    private static DownloadUtils mDownloadUtils;
    private static ThreadUtils mThreadUtils;


    private String mDownloadUrl;
    private String mDriPath;
    private String mFileName;


    private DownloadUtils() {

    }


    // 获取对象
    public static DownloadUtils getInstance() {
        if (mThreadUtils == null) {
            mThreadUtils = new ThreadUtils();
        }
        if (mDownloadUtils == null) {
            mDownloadUtils = new DownloadUtils();
        }
        return mDownloadUtils;
    }


    // 设置下载地址
    public DownloadUtils setUrl(String downloadUrl) {
        if (downloadUrl == null) {
            throw new NullPointerException("url is a null");
        }
        this.mDownloadUrl = downloadUrl;
        return mDownloadUtils;
    }


    // 设置下载文件夹
    public DownloadUtils setDirPath(String dirPath) {
        if (dirPath == null) {
            throw new NullPointerException("dirPath is a null");
        }
        this.mDriPath = dirPath;
        return mDownloadUtils;
    }


    // 设置下载文件名称
    public DownloadUtils setFileName(String fileName) {
        if (fileName == null) {
            throw new NullPointerException("fileName is a null");
        }
        this.mFileName = fileName;
        return mDownloadUtils;
    }


    // 设置下载进度回调监听
    public void setOnDownloadListener(OnDownloadListener listener) {
        if (listener == null) {
            throw new NullPointerException("OnDownloadListener is a null");
        }
        downLoadFile(mDownloadUrl, mDriPath, mFileName, listener);
    }


    /**
     * 下载文件
     *
     * @param downloadUrl
     * @param driPath
     * @param fileName
     * @param listener
     * @return file对象
     */
    public void downLoadFile(String downloadUrl, String driPath, String fileName, OnDownloadListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 先判空, 保证参数无误
                if (TextUtils.isEmpty(downloadUrl) || TextUtils.isEmpty(driPath) || TextUtils.isEmpty(fileName)) {
                    throw new NullPointerException("downloadUrl is a null");
                }
                if (TextUtils.isEmpty(driPath) || TextUtils.isEmpty(fileName)) {
                    throw new NullPointerException("driPath is a null");
                }
                if (TextUtils.isEmpty(fileName)) {
                    throw new NullPointerException("fileName is a null");
                }
                if (listener == null) {
                    throw new NullPointerException("OnDownloadListener is a null object");
                }


                // 输出一下下载信息
                Log.d("gLog", TAG + " - 文件下载 ------>> 文件下载地址: " + downloadUrl);
                Log.d("gLog", TAG + " - 文件下载 ------>> 文件保存路径: " + driPath);
                Log.d("gLog", TAG + " - 文件下载 ------>> 文件保存名称: " + fileName);


                mThreadUtils.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        listener.onStart();
                    }
                });


                // 下载准备
                int downloadedSize = 0;        // 已经下载的文件大小
                int fileTotalSize = 0;         // 文件总大小


                // 文件夹准备
                File file = new File(driPath);
                if (!file.exists()) {           // 判断文件夹是否存在
                    if (!file.mkdirs()) {       // 文件夹不存在, 创建
                        mThreadUtils.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                listener.onError("无法创建文件夹");
                            }
                        });
                        return;
                    }
                }


                // 文件全路径 = 文件夹+文件名+后缀
                file = new File(driPath + File.separator + fileName);
                if (file == null) {
                    mThreadUtils.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            listener.onError("无法创建文件");
                        }
                    });
                }


                // 流和链接
                InputStream inputStream = null;
                FileOutputStream outputStream = null;
                HttpURLConnection connection = null;


                // 开始链接
                try {
                    URL url = new URL(downloadUrl);
                    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 * 4];
                    int len;
                    while ((len = inputStream.read(buffer)) > 0) {
                        outputStream.write(buffer, 0, len);
                        downloadedSize += len;


                        // 计算文件下载进度
                        final int progress = (int) (downloadedSize * 1.0f / fileTotalSize * 100);


                        int finalFileTotalSize = fileTotalSize;
                        mThreadUtils.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                listener.onProgress(finalFileTotalSize, progress);
                            }
                        });
                    }


                    // 下载成功

                    File finalFile = file;
                    mThreadUtils.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            listener.onFinish(finalFile);
                        }
                    });
                } catch (Exception e) {
                    if (file.exists()) {
                        if (file.delete()) {
                            mThreadUtils.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    listener.onError("下载失败, 失败信息: " + e.getMessage());
                                }
                            });
                        } else {
                            mThreadUtils.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    listener.onError("下载失败, 失败信息: " + e.getMessage());
                                }
                            });
                        }
                    } else {
                        mThreadUtils.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                listener.onError("下载失败, 失败信息: " + e.getMessage());
                            }
                        });
                    }
                } finally {
                    try {
                        if (inputStream != null)
                            inputStream.close();
                        if (outputStream != null)
                            outputStream.close();
                        if (connection != null)
                            connection.disconnect();
                    } catch (Exception e) {
                        mThreadUtils.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                listener.onError("IO流关闭失败, 失败信息: " + e.getMessage());
                            }
                        });
                    }
                }
            }
        }).start();
    }


    /**
     * 回调监听器
     * 

* 所有回调函数都运行在主线程 */ public interface OnDownloadListener { // 开始下载 void onStart(); // 正在下载 void onProgress(int fileTotalSize, int progress); // 下载完成 void onFinish(File file); // 下载失败 void onError(String errMsg); } /** * 线程切换工具 */ private static class ThreadUtils { private Handler mHandler = new Handler(Looper.getMainLooper()); // 在主线程中运行 public void runOnUiThread(Runnable r) { if (Looper.myLooper() == Looper.getMainLooper()) { //主线程 r.run(); } else { //子线程 mHandler.post(r); } } // 在子线程中运行 public void runOnSubThread(Runnable r) { new Thread(r).start(); } // 是否是主线程 public boolean isMainThread() { return Looper.getMainLooper() == Looper.myLooper(); } } }

你可能感兴趣的:(下载工具类 - 基于 HttpURLConnection)