Android开发——断点续传原理以及实现

0. 前言
在开发中 , 断点续传听起来挺容易 , 在下载一个文件时点击暂停任务暂停 , 点击开始会继续下载文件 。但是真正实现起来知识点还是蛮多的 , 因此今天有时间实现了一下 , 并进行记录 。本文原创 , 转载请注明出处为的博客 。
1. 断点续传原理
在本地下载过程中要使用数据库实时存储到底存储到文件的哪个位置了 , 这样点击开始继续传递时 , 才能通过HTTP的GET请求中的()方法可以告诉服务器 , 数据从哪里开始 , 到哪里结束 。同时在本地的文件写入时 , 的seek()方法也支持在文件中的任意位置进行写入操作 。同时通过广播将子线程的进度告诉的 。
2. 的按钮响应
【Android开发——断点续传原理以及实现】当点击开始按钮时 , 将url写在了类的对象info中并通过从传递到了中 。这里使用()来区分是开始按钮还是暂停按钮 。
public class FileInfo implements Serializable{private String url; //URLprivate int length; //长度或结束位置private int start; //开始位置private int now;//当前进度//构造方法 , set/get略}//开始按钮逻辑 , 停止逻辑大致相同strat.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent = new Intent(MainActivity.this,DownLoadService.class);intent.setAction(DownLoadService.ACTION_START);intent.putExtra("fileUrl",info);startService(intent);}});
3. 在中的子线程中获取文件大小
在中的()中 , 将对象从中取出 , 如果是开始命令 , 则开启一个线程 , 根据该url去获得要下载文件的大小 , 将该大小写入对象并通过传回 , 同时在本地创建一个相同大小的本地文件 。暂停命令最后会讲到 。
public void run() {HttpURLConnection urlConnection = null;RandomAccessFile randomFile = null;try {URL url = new URL(fileInfo.getUrl());urlConnection = (HttpURLConnection) url.openConnection();urlConnection.setConnectTimeout(3000);urlConnection.setRequestMethod("GET");int length = -1;if (urlConnection.getResponseCode() == HttpStatus.SC_OK) {//获得文件长度length = urlConnection.getContentLength();}if (length <= 0) {return;}//创建相同大小的本地文件File dir = new File(DOWNLOAD_PATH);if (!dir.exists()) {dir.mkdir();}File file = new File(dir, FILE_NAME);randomFile = new RandomAccessFile(file, "rwd");randomFile.setLength(length);//长度给fileInfo对象fileInfo.setLength(length);//通过Handler将对象传递给ServicemHandle.obtainMessage(0, fileInfo).sendToTarget();} catch (Exception e) {e.printStackTrace();} finally {//流的回收逻辑略}}}
4. 数据库操作封装
在的()方法中拿到有属性的对象 , 并使用自定义的类进行具体的文件下载逻辑 。这里传入上下文 , 因为数据库处理操作需要用到 。
downLoadUtil = new DownLoadUtil(DownLoadService.this,info);downLoadUtil.download();
这里有一个数据库操作的接口 , 内部有增删改查等逻辑 , 用于记录下载任务的信息 。自定义一个类将这里的逻辑实现 , 内部数据库创建关于继承的自定义类的逻辑就不贴了 , 比较简单 , 该类会在类的构造方法中创建实例 。完成底层数据库操作的封装 。
public interface ThreadDAO {//插入一条数据public void insert(FileInfo info);//根据URL删除一条数据public void delete(String url);//根据URL更新一条进度public void update(String url,int finished);//根据URL找到一条数据public List