当前位置:K88软件开发文章中心编程语言APP编程Android01 → 文章内容

7.3.3 Android 文件下载(2)

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-12 6:26:52

本节引言:本节给大家带来的Android中的多线程断点续传的代码解析,呵呵,为什么叫解析呢?因为我也写不出来,( ╯□╰ )!先来说说断点的意思吧!所谓的断点就是:使用数据库记录每天线程所下载的进度!每次启动时根据线程id查询某线程的下载进度,在继续下载!听上去蛮简单的,要你写十有八九写不出,这很正常,所以本节看懂最好,看不懂也没什么,会用和改就好!好的,开始本节内容~Android多线程断点下载的代码流程解析:运行效果图:实现流程全解析:Step 1:创建一个用来记录线程下载信息的表创建数据库表,于是乎我们创建一个数据库的管理器类,继承SQLiteOpenHelper类重写onCreate()与onUpgrade()方法,我们创建的表字段如下:DBOpenHelper.java:package com.jay.example.db;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;public class DBOpenHelper extends SQLiteOpenHelper { public DBOpenHelper(Context context) { super(context, "downs.db", null, 1); } @Override public void onCreate(SQLiteDatabase db) { //数据库的结构为:表名:filedownlog 字段:id,downpath:当前下载的资源, //threadid:下载的线程id,downlength:线程下载的最后位置 db.execSQL("CREATE TABLE IF NOT EXISTS filedownlog " + "(id integer primary key autoincrement," + " downpath varchar(100)," + " threadid INTEGER, downlength INTEGER)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //当版本号发生改变时调用该方法,这里删除数据表,在实际业务中一般是要进行数据备份的 db.execSQL("DROP TABLE IF EXISTS filedownlog"); onCreate(db); }}Step 2:创建一个数据库操作类我们需要创建什么样的方法呢?①我们需要一个根据URL获得每条线程当前下载长度的方法②接着,当我们的线程新开辟后,我们需要往数据库中插入与该线程相关参数的方法③还要定义一个可以实时更新下载文件长度的方法④我们线程下载完,还需要根据线程id,删除对应记录的方法FileService.javapackage com.jay.example.db;import java.util.HashMap;import java.util.Map;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;/* * 该类是一个业务bean类,完成数据库的相关操作 * */public class FileService { //声明数据库管理器 private DBOpenHelper openHelper; //在构造方法中根据上下文对象实例化数据库管理器 public FileService(Context context) { openHelper = new DBOpenHelper(context); } /** * 获得指定URI的每条线程已经下载的文件长度 * @param path * @return * */ public Map<Integer, Integer> getData(String path) { //获得可读数据库句柄,通常内部实现返回的其实都是可写的数据库句柄 SQLiteDatabase db = openHelper.getReadableDatabase(); //根据下载的路径查询所有现场的下载数据,返回的Cursor指向第一条记录之前 Cursor cursor = db.rawQuery("select threadid, downlength from filedownlog where downpath=?", new String[]{path}); //建立一个哈希表用于存放每条线程已下载的文件长度 Map<Integer,Integer> data = new HashMap<Integer, Integer>(); //从第一条记录开始遍历Cursor对象 cursor.moveToFirst(); while(cursor.moveToNext()) { //把线程id与该线程已下载的长度存放到data哈希表中 data.put(cursor.getInt(0), cursor.getInt(1)); data.put(cursor.getInt(cursor.getColumnIndexOrThrow("threadid")), cursor.getInt(cursor.getColumnIndexOrThrow("downlength"))); } cursor.close();//关闭cursor,释放资源; db.close(); return data; } /** * 保存每条线程已经下载的文件长度 * @param path 下载的路径 * @param map 现在的di和已经下载的长度的集合 */ public void save(String path,Map<Integer,Integer> map) { SQLiteDatabase db = openHelper.getWritableDatabase(); //开启事务,因为此处需要插入多条数据 db.beginTransaction(); try{ //使用增强for循环遍历数据集合 for(Map.Entry<Integer, Integer> entry : map.entrySet()) { //插入特定下载路径特定线程ID已经下载的数据 db.execSQL("insert into filedownlog(downpath, threadid, downlength) values(?,?,?)", new Object[]{path, entry.getKey(), entry.getValue()}); } //设置一个事务成功的标志,如果成功就提交事务,如果没调用该方法的话那么事务回滚 //就是上面的数据库操作撤销 db.setTransactionSuccessful(); }finally{ //结束一个事务 db.endTransaction(); } db.close(); } /** * 实时更新每条线程已经下载的文件长度 * @param path * @param map */ public void update(String path,int threadId,int pos) { SQLiteDatabase db = openHelper.getWritableDatabase(); //更新特定下载路径下特定线程已下载的文件长度 db.execSQL("update filedownlog set downlength=? where downpath=? and threadid=?", new Object[]{pos, path, threadId}); db.close(); } /** *当文件下载完成后,删除对应的下载记录 *@param path */ public void delete(String path) { SQLiteDatabase db = openHelper.getWritableDatabase(); db.execSQL("delete from filedownlog where downpath=?", new Object[]{path}); db.close(); } }Step 3:创建一个文件下载器类好了,数据库管理器与操作类都完成了接着就该弄一个文件下载器类了,在该类中又要完成什么操作呢?要做的事就多了:①定义一堆变量,核心是线程池threads和同步集合ConcurrentHa

[1] [2] [3] [4] [5] [6]  下一页


7.3.3 Android 文件下载(2)