先来一张效果图:
主要实现思路:
每一个下载都是通过RandomAccessFile对下载资源的总长进行切割之后,根据我们设置的线程多少进行计算之后开启多线程下载的。而每一个任务都是一个AsyncTask。数据的存储都是通过SQL来进行,保证整个下载任务的断续不受影响。
一:数据库操作的工具类,根据数据库设计而生成的bean类:
public class DBHelper extends SQLiteOpenHelper{
//download.db-->数据库名
public DBHelper(Context context) {
super(context, "download.db", null, 1);
}
/**
* 在download.db数据库下创建一个download_info表存储下载信息
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table download_info(_id integer PRIMARY KEY AUTOINCREMENT, thread_id integer, "
+ "start_pos integer, end_pos integer, compelete_size integer,url char)");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
数据库操作类,包括查看,保存,更新,获取,以及下载完毕之后的删除操作。
public class Dao {
private static Dao dao=null;
private Context context;
private Dao(Context context) {
this.context=context;
}
public static Dao getInstance(Context context){
if(dao==null){
dao=new Dao(context);
}
return dao;
}
public SQLiteDatabase getConnection() {
SQLiteDatabase sqliteDatabase = null;
try {
sqliteDatabase= new DBHelper(context).getReadableDatabase();
} catch (Exception e) {
}
return sqliteDatabase;
}
/**
* 查看数据库中是否有数据
*/
public synchronized boolean isHasInfors(String urlstr) {
SQLiteDatabase database = getConnection();
int count = -1;
Cursor cursor = null;
try {
String sql = "select count(*) from download_info where url=?";
cursor = database.rawQuery(sql, new String[] { urlstr });
if (cursor.moveToFirst()) {
count = cursor.getInt(0);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != database) {
database.close();
}
if (null != cursor) {
cursor.close();
}
}
return count == 0;
}
/**
* 保存 下载的具体信息
*/
public synchronized void saveInfos(List<DownloadInfo> infos) {
SQLiteDatabase database = getConnection();
try {
for (DownloadInfo info : infos) {
String sql = "insert into download_info(thread_id,start_pos, end_pos,compelete_size,url) values (?,?,?,?,?)";
Object[] bindArgs = { info.getThreadId(), info.getStartPos(),
info.getEndPos(), info.getCompeleteSize(),
info.getUrl() };
database.execSQL(sql, bindArgs);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != database) {
database.close();
}
}
}
/**
* 得到下载具体信息
*/
public synchronized List<DownloadInfo> getInfos(String urlstr) {
List<DownloadInfo> list = new ArrayList<>();
SQLiteDatabase database = getConnection();
Cursor cursor = null;
try {
String sql = "select thread_id, start_pos, end_pos,compelete_size,url from download_info where url=?";
cursor = database.rawQuery(sql, new String[] { urlstr });
while (cursor.moveToNext()) {
DownloadInfo info = new DownloadInfo(cursor.getInt(0),
cursor.getInt(1), cursor.getInt(2), cursor.getInt(3),
cursor.getString(4));
list.add(info);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != database) {
database.close();
}
if (null != cursor) {
cursor.close();
}
}
return list;
}
/**
* 更新数据库中的下载信息
*/
public synchronized void updataInfos(int threadId, int compeleteSize, String urlstr) {
SQLiteDatabase database = getConnection();
try {
String sql = "update download_info set compelete_size=? where thread_id=? and url=?";
Object[] bindArgs = { compeleteSize, threadId, urlstr };
database.execSQL(sql, bindArgs);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != database) {
database.close();
}
}
}
/**
* 下载完成后删除数据库中的数据
*/
public synchronized void delete(String url) {
SQLiteDatabase database = getConnection();
try {
database.delete("download_info", "url=?", new String[] { url });
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != database) {
database.close();
}
}
}
}
根据数据库设计的字段自己编写的bean类:
public class DownloadInfo {
private int threadId;//下载器id
private int startPos;//开始点
private int endPos;//结束点
private int compeleteSize;//完成度
private String url;//下载器网络标识
public DownloadInfo(int threadId, int startPos, int endPos,
int compeleteSize,String url) {
this.threadId = threadId;
this.startPos = startPos;
this.endPos = endPos;
this.compeleteSize = compeleteSize;
this.url=url;
}
public DownloadInfo() {
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getThreadId() {
return threadId;
}
public void setThreadId(int threadId) {
this.threadId = threadId;
}
public int getStartPos() {
return startPos;
}
public void setStartPos(int startPos) {
this.startPos = startPos;
}
public int getEndPos() {
return endPos;
}
public void setEndPos(int endPos) {
this.endPos = endPos;
}
public int getCompeleteSize() {
return compeleteSize;
}
public void setCompeleteSize(int compeleteSize) {
this.compeleteSize = compeleteSize;
}
@Override
public String toString() {
return "DownloadInfo [threadId=" + threadId