android中利用多线程实现断点下载

多线程

首先我们要下载的文件是比较大的,有一两百M,因为单线程下载会非常慢,用户肯定是没有耐心去等待的,体验也会大打折扣,所以我采取了多线程的下载方式,同时采用了线程池的方式来管理多线程。因为线程池可以限制系统中执行线程的数量,根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果

线程池

使用线程池有三点好处

第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。

第二:提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。

第三:提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控

java中主要用到的线程池有下面四种

  • newSingleThreadExecutor
    创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
  • newFixedThreadPool
    创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
  • newCachedThreadPool
    创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,
    那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
  • newScheduledThreadPool
    创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

JAVA线程池的分析和使用

Java线程池使用说明

多线程下载的原理

1、在本地创建一个大小跟服务器文件相同大小的临时文件。

2、计算分配几个线程去下载服务器上的资源,知道每个线程下载文件的位置。

从上面的原理可以看出,多线程下载就是讲一个文件分成几段,然后每段分别开线程去下载,可是我们平时在访问一个文件时都是对整个文件进行读写,那怎样才能进行分段访问呢?那就要用到下面它RandomAccessFile了,它是一个随机文件访问类

我们在多线程断点下载的过程中,主要用到它的seek方法,

1
2
3
void seek(long pos)
This method sets the file-pointer offset, measured from the beginning of this file, at which the next read or write occurs.

这个方法可以将文件的操作位置指向任何地方,其实所谓的断点下载就是利用的这点,让我们在下载过程中点击了暂停,我们记下此时文件已经下载的位置,当我们点继续下载的时候,我们只需拿到这个位置,然后调用seek方法,就可继续上次的下载了,而不用重新下载

最后贴两个写的比较好的两个开源库

FileDownloader

MultiThreadDownload