zoukankan      html  css  js  c++  java
  • 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();
    		}
    
    	}
    
    }
    

    目录结构如下:



  • 相关阅读:
    实战 Windows下搭建Objectivec的编译环境
    C# 协变和逆变 精解(直观明了,简单易懂)
    求两个字符串的最大公共串
    [C++][数据结构]队列(queue)的实现
    转换一个矩阵(2维数组)为HTML Table
    [C++][数据结构][算法]单链式结构的深拷贝
    LaTeX 中的特殊符号
    [C++11][数据结构]自己的双链表实现
    现代诗十则
    [C++11][算法][穷举]输出背包问题的所有可满足解
  • 原文地址:https://www.cnblogs.com/lanzhi/p/6469508.html
Copyright © 2011-2022 走看看