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来操作数据库 ...
随机推荐
- 格式化时间的一个好方法(补充moment)
/** * * 格式化时间 * @param {*} time * @param {*} fmt * @returns * time(new Date(), 'yyyy/MM/dd') ==> ...
- (转)如何启动或关闭数据库的归档(ARCHIVELOG)模式
转自:http://www.eygle.com/archives/2004/10/oracle_howtoeci.html Oracle数据库可以运行在2种模式下:归档模式(archivelog)和非 ...
- js用button激活 Alert 元素关闭按钮的交互功能
js用button激活 Alert 元素关闭按钮的交互功能 一.总结 1.点(.)对应class,井号(#)对应id 2.jquery:amaze里面用的jquery,jquery熟悉之后,这些东西 ...
- RTC时钟和BKP的配置stm32
摘自:https://blog.csdn.net/gtkknd/article/details/52233605 RTC和后备寄存器通过一个开关供电,在VDD有效的时候选择VDD供电,否则选择VBAT ...
- php 发送QQ邮箱邮件
这是我的源码比较简陋 https://www.lanzous.com/i2l7h8f 感谢 https://www.cnblogs.com/woider/p/6980456.html 下载phpmai ...
- STATUS CODE: 91, occurs when trying to move media from one volume pool to another.
Overview:Symantec NetBackup (tm) will not allow a tape with active images to be moved from one volum ...
- web中的重定向与转发
Redirect:重定向(客户端重定向) 是HTTP协议规定的一种机制:当client向server发送一个请求,要求获取一个资源时,在server接收到这个请求后发现请求的这个资源实际存放在另一个位 ...
- php 小程序获取渠道二维码 保存
function ppost($url,$arr){ $post_data = json_encode($arr); $url=$url; $ch = curl_init(); curl_setopt ...
- Coverage报告生成
Coverage报告生成 覆盖率 覆盖率驱动的验证方法中覆盖率报告的生成至关重要,现在介绍一下使用DVE和URG生成覆盖率报告的步骤. 使用VCS生成数据 在VCS的运行脚本中添加-cm cond+f ...
- [Now] Update an application hosted with Zeit’s Now
Because now deploys are immutable, you can’t push changes to a running instance - you just push a ne ...