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 {
		/**
		 * 構造函數
		 */
		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();
		}

	}

}

目錄結構如下:

發佈留言