Android中数据库和安装包分离
我们在做Android应用尤其是商业应用的时候,很多时候都需要后期版本升级,如果我们的数据库文件非常大,比如游戏之类的,这时候就不应该每次版本更新都去重新复制数据库。将数据库和安装包分离,下面来详细介绍:
(1)判断是否是第一次安装
try {
//获取程序的当前版本
PackageInfo info = getPackageManager().getPackageInfo(PACKAGE_NAME, 0);
currentVersion = info.versionCode;
//获取上一个版本
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
lastVersion = prefs.getInt(VERSION_KEY, 0);
System.out.println("当前版本是版本"+currentVersion);
//判断是否是第一次安装
if(currentVersion > lastVersion){
//如果当前版本大于上次版本,说明该版本安装文件属于第一次启动
initDatabase();
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
(2)如果是第一次安装,则需要判断是否有数据库文件,如果没有则需要复制
private void initDatabase(){
Toast.makeText(this, "不同版本", 2000);
//获取数据库文件要存放的路径
databaseFilename = DATABASE_PATH + "/" + DATABASE_FILENAME;
File dir = new File(DATABASE_PATH);
//如果目录不存在,创建这个目录
if(!dir.exists()){
dir.mkdir();
}
//数据库文件是否已存在,不存在则导入
if(!(new File(databaseFilename)).exists()){
StartFrameTask startFrameTask = new StartFrameTask();
startFrameTask.execute();
}else{
System.out.println("数据库已经存在");
}
}
(3)如果还没有数据库文件,则启动异步任务来复制
private void copyDataBase(){
try{
// 获得InputStream对象
InputStream is = getResources().openRawResource(R.raw.cpdata);
pd.setMax(is.available());
FileOutputStream fos = new FileOutputStream(databaseFilename);
byte[] buffer = new byte[1024];
int count = 0;
// 开始复制db文件
int process = 0;
while ((count = is.read(buffer)) > 0) {
fos.write(buffer, 0, count);
process += count;
pd.setProgress(process);
}
fos.close();
is.close();
}catch(Exception e){
e.printStackTrace();
}
}
实例代码如下:
package com.example.testsqlite; import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream; import android.app.Activity;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.widget.Toast; public class MainActivity extends Activity {
private static final String PACKAGE_NAME = "com.example.testsqlite";
private static final String VERSION_KEY = "versionCode";
private static final String DATABASE_PATH = "data/data/com.example.testsqlite";
private static final String DATABASE_FILENAME = "cpdata.db";
private int currentVersion;
private int lastVersion;
private ProgressDialog pd;
private String databaseFilename;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); try {
//获取程序的当前版本
PackageInfo info = getPackageManager().getPackageInfo(PACKAGE_NAME, 0);
currentVersion = info.versionCode;
//获取上一个版本
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
lastVersion = prefs.getInt(VERSION_KEY, 0);
System.out.println("当前版本是版本"+currentVersion);
//判断是否是第一次安装
if(currentVersion > lastVersion){
//如果当前版本大于上次版本,说明该版本安装文件属于第一次启动
initDatabase();
}
} catch (NameNotFoundException e) {
e.printStackTrace();
}
} private void initDatabase(){
Toast.makeText(this, "不同版本", 2000);
//获取数据库文件要存放的路径
databaseFilename = DATABASE_PATH + "/" + DATABASE_FILENAME;
File dir = new File(DATABASE_PATH);
//如果目录不存在,创建这个目录
if(!dir.exists()){
dir.mkdir();
}
//数据库文件是否已存在,不存在则导入
if(!(new File(databaseFilename)).exists()){
StartFrameTask startFrameTask = new StartFrameTask();
startFrameTask.execute();
}else{
System.out.println("数据库已经存在");
}
} private void copyDataBase(){
try{
// 获得InputStream对象
InputStream is = getResources().openRawResource(R.raw.cpdata);
pd.setMax(is.available());
FileOutputStream fos = new FileOutputStream(databaseFilename);
byte[] buffer = new byte[1024];
int count = 0;
// 开始复制db文件
int process = 0;
while ((count = is.read(buffer)) > 0) {
fos.write(buffer, 0, count);
process += count;
pd.setProgress(process);
}
fos.close();
is.close();
}catch(Exception e){
e.printStackTrace();
}
} /**
* 开启进度对话框
*/
private void startProgressDialog() {
if (pd == null) {
pd = new ProgressDialog(this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("正在初始化数据库文件");
pd.setCancelable(false);
}
pd.show();
} /**
* 停止进度对话框
*/
private void stopProgressDialog() {
if (pd != null) {
pd.dismiss();
pd = null;
} } /**
* 创建异步任务
*
* @author 李小强
*
*/
public class StartFrameTask extends AsyncTask<Integer, String, Integer> {
/**
* 构造函数
*/
public StartFrameTask() { } /**
* 调用取消时
*/
@Override
protected void onCancelled() {
stopProgressDialog();
super.onCancelled();
} /**
* 后台线程查询数据
*/
@Override
protected Integer doInBackground(Integer... params) {
copyDataBase();
return null;
} /**
* 该方法将在执行后台耗时操作前被调用
*/
@Override
protected void onPreExecute() {
startProgressDialog();
} /**
* 将doInBackground()的返回值传给该方法
*/
@Override
protected void onPostExecute(Integer result) {
stopProgressDialog();
} } }
目录结构如下:
Android中数据库和安装包分离的更多相关文章
- Android中数据库的操作流程详解
Android中数据库的操作方法: 1.Android平台提供了一个数据库辅助类来创建或打开数据库. 这个辅助类继承自SQLiteOpenHelper类.继承和扩展SQLiteOpenHelper类主 ...
- Android学习记录(2)—Android中数据库的常见操作
android中数据库操作是非常常见了,我们会经常用到,操作的方法也有很多种形式,这里我就把最常见的两种形式记录下来了,以备以后用到方便查看.我就不写注释和解释了,因为android数据库的操作和其它 ...
- Android中数据库Sqlite的性能优化
1.索引简单的说,索引就像书本的目录,目录可以快速找到所在页数,数据库中索引可以帮助快速找到数据,而不用全表扫描,合适的索引可以大大提高数据库查询的效率.(1). 优点大大加快了数据库检索的速度,包括 ...
- 关于android中数据库的创建以及基础的增删改查的相应操作
这里主要是掌握一些基本的相应的知识,具体的是阿金是等到明天在进行. 相应的知识点如下: 对于数据库中的一些常识.SQLite 没有服务器进程,它通过文件保存数据,该文件是跨平台的,可以放在其他平台中使 ...
- android中的数据库操作
如何在android中调用数据库资源 在android中主要有两种方法来实现对数据库的访问,一种是adb shell方式,另一种是通过相关的android 的java类来间接的对数据库来进行操作.其中 ...
- android中的数据库操作(转)
android中的数据库操作 android中的应用开发很难避免不去使用数据库,这次就和大家聊聊android中的数据库操作. 一.android内的数据库的基础知识介绍 1.用了什么数据库 an ...
- android中的数据库操作(SQLite)
android中的数据库操作 android中的应用开发很难避免不去使用数据库,这次就和大家聊聊android中的数据库操作. 一.android内的数据库的基础知识介绍 1.用了什么数据库 an ...
- Android学习记录(3)—Android中ContentProvider的基本原理学习总结
一.ContentProvider简介 当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.虽然使用其他方法也可以对外共享数据 ...
- 我的Android六章:Android中SQLite数据库操作
今天学习的内容是Android中的SQLite数据库操作,在讲解这个内容之前小编在前面有一篇博客也是讲解了SQLite数据库的操作,而那篇博客的讲解是讲述了 如何在Window中通过DOM来操作数据库 ...
随机推荐
- Java Callable Future Example(java 关于Callable,Future的例子)
Home » Java » Java Callable Future Example Java Callable Future Example April 3, 2018 by Pankaj 25 C ...
- php课程 8-30 实现验证码验证的难点是什么
php课程 8-30 实现验证码验证的难点是什么 一.总结 一句话总结:session技术实现验证码传递. 1.生成验证码的那个网页(php文件)中的验证码怎么搁到别的网页中去? 直接在img的src ...
- how to query for a list<String> in jdbctemplate?--转载
原文地址:http://stackoverflow.com/questions/13354158/how-to-query-for-a-liststring-in-jdbctemplate I'm ...
- 清除浮动.md
清除浮动的三种方法 1 加空div层(.clear) 2 overflow属性设置(.clearo) 3 :after伪元素(.clearfix) <!DOCTYPE html> < ...
- 14、编写一个通用的Makefile
编译test_Makefile的方法:a. gcc -o test a.c b.c对于a.c: 预处理.编译(C文件转换成汇编).汇编(汇编转换成机器码)对于b.c:预处理.编译.汇编最后链接优点:命 ...
- AE加载不同数据的方法(GeoDatabase空间数据管理)
原文 AE加载不同数据的方法(GeoDatabase空间数据管理) GeoDatabase 先看一下GeoDatabase核心结构模型图: 1 工作空间工厂WorkspaceFactory对象 Wo ...
- [Node.js] Testing ES6 Promises in Node.js using Mocha and Chai
Writing great ES6 style Promises for Node.js is only half the battle. Your great modules must includ ...
- 交换排序(java)
package exchange_sort; import java.util.Random; /*各类交换排序 * ------数据存储范围1~s.length-1 ------ *主要包含 ...
- php实现从尾到头打印列表
php实现从尾到头打印列表 一.总结 4.数组倒序:array_reverse() 5.函数肯定要return,而不是echo 二.php实现从尾到头打印列表 输入一个链表,从尾到头打印链表每个节点的 ...
- thinkphp 3.2 updateFields 设置之后保存失败
// 检测提交字段的合法性 if(isset($this->options['field'])) { // $this->field('field1,field2...')->cre ...