《Kotlin系列》之协程+Flow+Okhttp3实现多任务下载(暂停、继续)

这是一个Android下载管理器的实现,包括DownloadManager类、DownloadInfo类、DownloaderCallBack接口和ResponseProgressBody类。DownloadManager支持设置最大并发数、取消、暂停全部下载任务,以及添加、管理下载任务。DownloadInfo用于存储下载任务的状态和信息。DownloaderCallBack定义了下载过程中的回调方法,如进度更新、完成、暂停和取消。ResponseProgressBody是下载响应的拦截器,用于实时更新下载进度。

先看看效果图

请添加图片描述

封装

  • 1、下载器:DownloadManager

class DownloadManager(context: Context?) {
   
   


    private var completeInfo: MutableMap<String, DownloadInfo>? = HashMap()
    private var downloadInfo: MutableMap<String, DownloadInfo>? = HashMap()

    private var client: OkHttpClient? = null

    private var context: Context? = null

    private var maxRequests = 5 //最大并发数

    companion object {
   
   


        const val DOWNLOAD_STATE_WAITING = 0x00 //等待

        const val DOWNLOAD_STATE_DOWNLOADING = 0x01 //下载中

        const val DOWNLOAD_STATE_PAUSE = 0x02 //暂停

        const val DOWNLOAD_STATE_CANCLE = 0x03 //取消

        const val DOWNLOAD_STATE_FINISH = 0x04 //完成

        const val DOWNLOAD_STATE_FAIL = 0x05 //失败

        const val DOWNLOAD_STATE_RESTART = 0x06 //重新下载


        const val DOWNLOAD_MAPS = "DOWNLOAD_MAPS" //下载队列的
        const val COMPLETE_MAPS = "COMPLETE_MAPS" //已完成的

        @SuppressLint("StaticFieldLeak")
        private var instance: DownloadManager? = null


        fun get(context: Context?): DownloadManager {
   
   
            if (instance == null) {
   
   
                synchronized(DownloadManager::class.java) {
   
   
                    if (instance == null) {
   
   
                        instance = DownloadManager(context)
                    }
                }
            }
            return instance!!
        }
    }

    init {
   
   
        init(context)
    }


    /**
     * 初始化一些配置
     */
    private fun init(context: Context?) {
   
   
        client = OkHttpClient()
        client?.dispatcher()?.maxRequests = maxRequests
        this.context = context


        downloadInfo = PrefsUtil.getInstance()?.getMap(DOWNLOAD_MAPS)

        if (downloadInfo == null) {
   
   
            downloadInfo = HashMap()
        }

        completeInfo = PrefsUtil.getInstance()?.getMap(COMPLETE_MAPS)
        if (completeInfo == null) {
   
   
            completeInfo = HashMap()
        }

    }

    /**
     *保存当前任务
     */
    fun saveDownloadInfo(key: String?, downloadInfo: MutableMap<String, DownloadInfo>?) {
   
   
        key?.let {
   
    PrefsUtil.getInstance()?.putMap(it, downloadInfo) }
    }


    /**
     * 设置最大并发
     */
    fun setMaxRequests(maxRequests: Int): DownloadManager {
   
   
        this.maxRequests = maxRequests
        return this
    }


    /**
     * 取消全部下载
     */
    fun cancelAll() {
   
   
        if (client != null) {
   
   
            for (call in client?.dispatcher()?.queuedCalls()!!) {
   
   
                cancel(call.request().tag().toString())
            }
            for (call in client?.dispatcher()?.runningCalls()!!) {
   
   
                cancel(call.request().tag().toString())
            }
        }
    }

    /**
     * 取消下载
     *
     * @param url
     */
    fun cancel(url: String?) {
   
   
        if (client != null) {
   
   
            for (call in client?.dispatcher()?.queuedCalls()!!) {
   
   
                if (call.request().tag() == url) call.cancel()
            }
            for (call in client?.dispatcher()?.runningCalls()!!) {
   
   
                if (call.request().tag() == url) call.cancel()
            }
        }
        if (downloadInfo?.get(url) != null) {
   
   
            val cancelInfo: DownloadInfo? = downloadInfo?.get(url)
            cancelInfo?.setDownloadState(DOWNLOAD_STATE_CANCLE)
            downloadInfo?.remove(cancelInfo?.getUrl())
            saveDownloadInfo(DOWNLOAD_MAPS, downloadInfo)
            val file = File(cancelInfo?.getTargetUrl().toString())
            if (file.exists()) file.delete()
        }
    }

    /**
     * 暂停全部下载
     */
    fun pauseAll() {
   
   
        if (client != null) {
   
   
            for (call in client?.dispatcher()?.queuedCalls(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值