我们在做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目录结构如下:{ /** * 构造函数 */ 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(); } }}