第二阶段 7、添加数据库逻辑,防止App被强杀后的数据丢失
2016-01-15 13:55
363 查看
应用场景:
场景一:退出应用,任务在后台服务中执行,再次进入应用时,显示的数据会不同步。
场景二:下载数据存在内存中,当应用被强杀后,再次进入应用时,数据会被清空。
解决思路:
场景一:上一阶段中创建的mOperatedEntries集合中保存的是所有被操作过的最新的下载Entry,可在onCreate()方法中将当前显示的entry的最新状态从mOperatedEntries集合中提取出来。
场景二:既然存储在内存中会被清除,那就存储在数据库中,每次Entry的状态改变时,除去往mOperatedEntries集合中存储之外,还要往数据库中存储一份,而调用时只在创建DownloadService时调用一次,即只在Service类中的onCreate()方法中调用一次
解决方案:
场景一的解决方案
场景二的解决方案:
相关知识来源:
stay老兄的有心课堂-自己动手写多任务下载框架
场景一:退出应用,任务在后台服务中执行,再次进入应用时,显示的数据会不同步。
场景二:下载数据存在内存中,当应用被强杀后,再次进入应用时,数据会被清空。
解决思路:
场景一:上一阶段中创建的mOperatedEntries集合中保存的是所有被操作过的最新的下载Entry,可在onCreate()方法中将当前显示的entry的最新状态从mOperatedEntries集合中提取出来。
场景二:既然存储在内存中会被清除,那就存储在数据库中,每次Entry的状态改变时,除去往mOperatedEntries集合中存储之外,还要往数据库中存储一份,而调用时只在创建DownloadService时调用一次,即只在Service类中的onCreate()方法中调用一次
解决方案:
场景一的解决方案
1、DataChanger
// 创建queryDownloadEntryById(String id)方法,通过该方法可从mOperatedEntries集合中取出所需的Entry public DownloadEntry queryDownloadEntryById(String id) { return mOperatedEntries.get(id); }
2、DownloadManager
// 调用DantaChanger中的queryDownloadEntryById方法,提供给外部使用 public DownloadEntry queryDownloadEntry(String id) { return DataChanger.getInstance(context).queryDownloadEntryById(id); }
3、ListActivity
// onCreate()方法中在创建完所需的下载Entry之后,根据创建的Entry的id,从mDownloadEntries中取出最新状态的Entry,在对应位置替换掉 DownloadEntry entry = null; DownloadEntry realEntry = null; for (int i = 0; i < mDownloadEntries.size(); i++) { entry = mDownloadEntries.get(i); realEntry = mDownloadManager.queryDownloadEntry(entry.id); if (realEntry != null) { mDownloadEntries.remove(i); mDownloadEntries.add(i, realEntry); } }
场景二的解决方案:
1、OrmDBHelper
// 创建数据库助手类 public class OrmDBHelper extends OrmLiteSqliteOpenHelper{ public static final String DB_NAME = "fsf_downloader"; public static final int DB_VERSION = 1; public OrmDBHelper(Context context, String databaseName, CursorFactory factory, int databaseVersion) { super(context, databaseName, factory, databaseVersion); } public OrmDBHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase database, ConnectionSource connectionSource) { try { TableUtils.createTable(connectionSource, DownloadEntry.class); } catch (SQLException e) { e.printStackTrace(); } } @Override public void onUpgrade(SQLiteDatabase arg0, ConnectionSource arg1, int arg2, int arg3) { } }
2、DBController
创建数据库控制类public class DBController { private static DBController instance; private SQLiteDatabase mDB; private OrmDBHelper mDBhelper; private DBController(Context context) { mDBhelper = new OrmDBHelper(context); mDB = mDBhelper.getWritableDatabase(); } public static DBController getInstance(Context context) { if (instance == null) { instance = new DBController(context); } return instance; } public synchronized void newOrUpdate(DownloadEntry entry) { try { Dao<DownloadEntry, String> dao = mDBhelper .getDao(DownloadEntry.class); dao.createOrUpdate(entry); } catch (SQLException e) { e.printStackTrace(); } } public synchronized ArrayList<DownloadEntry> queryAll() { Dao<DownloadEntry, String> dao; try { dao = mDBhelper.getDao(DownloadEntry.class); return (ArrayList<DownloadEntry>) dao.query(dao.queryBuilder() .prepare()); } catch (SQLException e) { Trace.e(e.getMessage()); return null; } } public synchronized DownloadEntry queryById(String id) { try { Dao<DownloadEntry, String> dao = mDBhelper.getDao(DownloadEntry.class); return dao.queryForId(id); } catch (SQLException e) { Trace.e(e.getMessage()); return null; } } }
3、DownloadEntry
@DatabaseTable(tableName = "downloadentry") public class DownloadEntry implements Serializable { @DatabaseField(id = true) public String id; @DatabaseField public String name; @DatabaseField public String url; @DatabaseField public DownloadStatus status = DownloadStatus.idle; @DatabaseField public int currentLength; @DatabaseField public int totalLength; public DownloadEntry() { } public DownloadEntry(String url) { this.url = url; this.name = url.substring(url.lastIndexOf("/") + 1); } public enum DownloadStatus { idle, waiting, downloading, paused, resumed, cancelled, completed } @Override public String toString() { return "DownloadEntry: " + url + " is " + status.name() + " with " + currentLength + "/" + totalLength; } @ c2f5 Override public boolean equals(Object o) { return o.hashCode() == this.hashCode(); } @Override public int hashCode() { return id.hashCode(); } }
4、DataChanger
// 将最新状态的Entry存入mOperatedEntries之后,再存入本地数据库 public void postStatus(DownloadEntry entry) { mOperatedEntries.put(entry.id, entry); DBController.getInstance(context).newOrUpdate(entry); setChanged(); notifyObservers(entry); }
5、DownloadService
// 创建服务的同时,创建数据库 @Override public void onCreate() { super.onCreate(); mExecutors = Executors.newCachedThreadPool(); mDataChanger = DataChanger.getInstance(getApplicationContext()); mDBController = DBController.getInstance(getApplicationContext()); // 取出数据库中存储的Entry ArrayList<DownloadEntry> mDownloadEntries = mDBController.queryAll(); if (mDownloadEntries != null) { for (DownloadEntry entry : mDownloadEntries) { // 重新创建服务后,所有的任务都要处于静止状态,然后再一次加入下载集合中 if (entry.status == DownloadEntry.DownloadStatus.downloading || entry.status == DownloadEntry.DownloadStatus.waiting) { entry.status = DownloadEntry.DownloadStatus.paused; // TODO add a config if need to recover download // 加入到下载队列中 addDownload(entry); } // 更新mOperatedEntries集合 mDataChanger.addToOperatedEntryMap(entry.id, entry); } } }
6、SplashActivity
// 优化:将DownloadManager放到闪屏页初始化 public class SplashActivity extends Activity{ @SuppressLint("HandlerLeak") private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { jumpTo(); }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); DownloadManager.getInstance(getApplicationContext()); mHandler.sendEmptyMessageDelayed(0, 2000); } private void jumpTo() { Intent intent = new Intent(this, ListActivity.class); startActivity(intent); } }
相关知识来源:
stay老兄的有心课堂-自己动手写多任务下载框架
相关文章推荐
- Android之获取手机上的图片和视频缩略图thumbnails
- 个人信息安全报告发布:有 APP 每分钟调用位置权限 1468 次
- 数据库链接字符串查询网站
- 下载量超过一亿的流行应用被发现含有恶意模块
- DB2实例管理
- DB2实例管理
- 苹果与Siri的七年之痒:“宫斗”戏码不断上演
- 保障MySQL数据安全的14个最佳方法
- mysql问答汇集
- 创建一个空的IBM DB2 ECO数据库的方法
- Access 2000 数据库 80 万记录通用快速分页类
- 开通一个数据库失败的原因的和解决办法
- 一个简单的asp数据库操作类
- CentOS下DB2数据库安装过程详解
- EasyASP v1.5发布(包含数据库操作类,原clsDbCtrl.asp)第1/2页
- sql2008 还原数据库解决方案
- Oracle 数据库自动存储管理-安装配置
- Oracle数据库执行脚本常用命令小结
- Oracle 数据库 临时数据的处理方法