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();
		}

	}

}

目录结构如下:



原文地址:https://www.cnblogs.com/lanzhi/p/6469508.html