如何从Android的一个辅助类初始化SQLite数据库一次 [英] How to initialize sqlite database once from a helper class in Android

查看:194
本文介绍了如何从Android的一个辅助类初始化SQLite数据库一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有延伸SQLiteOpenHelper,它看起来像这样一个自定义DataBaseHelper类:

 包com.stampii.stampii.comm.rpc;


进口的java.io.File;
进口java.io.FileOutputStream中;
进口java.io.IOException异常;
进口的java.io.InputStream;
进口java.io.OutputStream中;
进口java.sql.ResultSet中;

进口android.content.ContentValues​​;
进口android.content.Context;
进口android.database.Cursor;
进口android.database.sqlite.SQLiteDatabase;
进口android.database.sqlite.SQLiteDatabase.CursorFactory;
进口android.database.sqlite.SQLiteException;
进口android.database.sqlite.SQLiteOpenHelper;
进口android.util.Log;

公共类DataBaseHelper扩展SQLiteOpenHelper {

    私有静态SQLiteDatabase sqliteDb;
    私有静态DataBaseHelper实例;
    私有静态最终诠释DATABASE_VERSION = 1;
    //默认的数据库路径是:
    // /数据/数据​​/ pkgNameOfYou​​rApplication /数据库/
    私有静态字符串DB_PATH_ preFIX =/数据/数据​​/;
    私有静态字符串DB_PATH_SUFFIX =/数据库/;
    私有静态最后字符串变量=DataBaseHelper;
    私人上下文的背景下;

    / ***
     *构造器
     *
     * @参数方面
     *:应用程序上下文
     * @参数名称
     *:数据库名称
     * @参数厂
     *:光标厂
     * @参数版本
     *:DB版
     * /
    公共DataBaseHelper(上下文的背景下,字符串名称,
                    CursorFactory工厂,INT版){
            超(背景下,名称,厂家,版本);
            this.context =背景;
            Log.i(TAG,创建或打开数据库:+姓名);
    }

    / ***
     *初始化方法
     *
     * @参数方面
     *:应用程序上下文
     * @参数DATABASENAME
     *:数据库名称
     * /
    公共静态无效初始化(上下文的背景下,字符串DATABASENAME){
            如果(例如== NULL){
                    / **
                     *尝试检查是否有DB的资产原件
                     * 目录
                     * /
                    如果(!checkDatabase(上下文,DATABASENAME)){
                            //如果不存在,我试着从资产目录复制
                            尝试 {
                                copyDataBase(背景下,数据库名称);
                            }赶上(IOException异常E){
                                    Log.e(TAG,数据库+数据库名+并不存在,没有原始版本的资产目录);
                            }
                    }

                    Log.i(TAG,尝试创建数据库(实例+ DATABASENAME
                                    +));
                    例如=新DataBaseHelper(背景下,数据库名称,
                                    空,DATABASE_VERSION);
                    sqliteDb = instance.getWritableDatabase();
                    Log.i(TAG,+数据库名+数据库(实例,创建)!);
            }
    }

    / ***
     *静态方法获取单个实例
     *
     * @参数方面
     *:应用程序上下文
     * @参数DATABASENAME
     *:数据库名称
     * @返回:一个实例
     * /
    公共静态最终DataBaseHelper的getInstance(
                    上下文的背景下,字符串DATABASENAME){
            初始化(背景下,数据库名称);
            返回实例;
    }

    / ***
     *方法获取数据库实例
     *
     * @返回数据库实例
     * /
    公共SQLiteDatabase getDatabase(){
            返回sqliteDb;
    }

    @覆盖
    公共无效的onCreate(SQLiteDatabase DB){
            Log.d(TAG的onCreate:无关);

    }

    @覆盖
    公共无效onUpgrade(SQLiteDatabase分贝,INT oldVersion,诠释静态网页){
            Log.d(TAG,onUpgrade:无关);

    }

    / ***
     *法复制数据库的资产目录中应用程序的数据
     * 目录
     *
     * @参数DATABASENAME
     *:数据库名称
     * @throws IOException异常
     *:异常,如果文件不存在
     * /
    公共无效copyDataBase(字符串数据库名称)抛出IOException异常{
            copyDataBase(背景下,数据库名称);
    }

    / ***
     *从资产目录复制数据库应用程序的静态方法
     *数据目录
     *
     * @参数aContext
     *:应用程序上下文
     * @参数DATABASENAME
     *:数据库名称
     * @throws IOException异常
     *:异常,如果文件不存在
     * /
    私有静态无效copyDataBase(上下文aContext,串DATABASENAME)
                    抛出IOException异常{

            //打开本地数据库作为输入流
            InputStream的myInput = aContext.getAssets()开(数据库名称)。

            //路径刚刚创建的空分贝
            字符串outFileName = getDatabasePath(aContext,数据库名称);

            Log.i(TAG,检查创建目录:+ DB_PATH_ preFIX
                            + aContext.getPackageName()+ DB_PATH_SUFFIX);

            //如果路径不首先存在,创建它
            文件F =新的文件(DB_PATH_ preFIX + aContext.getPackageName()
                            + DB_PATH_SUFFIX);
            如果(!f.exists())
                    f.mkdir();

            Log.i(TAG,试图本地数据库复制到:+ outFileName);

            //打开空分贝的输出流
            的OutputStream myOutput =新的FileOutputStream(outFileName);

            //传输的字节从inputfile中的OUTPUTFILE
            byte []的缓冲区=新的字节[1024];
            INT长;
            而((长度= myInput.read(缓冲液))大于0){
                    myOutput.write(缓冲液,0,长度);
            }

            //关闭流
            myOutput.flush();
            myOutput.close();
            myInput.close();

            Log.i(TAG,DB(+数据库名称+)复制!);
    }

    / ***
     *方法来检查是否数据库存在于应用程序的数据目录
     *
     * @参数DATABASENAME
     *:数据库名称
     * @返回:布尔(true如果存在的话)
     * /
    公共布尔checkDatabase(字符串DATABASENAME){
            返回checkDatabase(背景下,数据库名称);
    }

    / ***
     *静态方法来检查,如果数据库存在于应用程序的数据目录
     *
     * @参数aContext
     *:应用程序上下文
     * @参数DATABASENAME
     *:数据库名称
     * @返回:布尔(true如果存在的话)
     * /
    私有静态布尔checkDatabase(上下文aContext,串DATABASENAME){
            SQLiteDatabase CHECKDB = NULL;

            尝试 {
                    字符串mypath中= getDatabasePath(aContext,数据库名称);

                    Log.i(TAG,试图conntect为:+ mypath中);
                    CHECKDB = SQLiteDatabase.openDatabase(mypath中,空,
                                    SQLiteDatabase.OPEN_READONLY);
                    Log.i(TAG,数据库+数据库名+找到了!);
                    checkDB.close();
            }赶上(SQLiteException E){
                    Log.i(TAG,数据库+数据库名+不存在!);

            }

            返回CHECKDB!= NULL?真假;
    }

    / ***
     *方法返回数据库路径在应用程序的数据目录
     *
     * @参数DATABASENAME
     *:数据库名称
     * @返回:完整路径
     * /
    私人字符串getDatabasePath(最后弦乐DATABASENAME){
            返回getDatabasePath(背景下,数据库名称);
    }

    / ***
     *静态方法返回数据库路径中的应用程序的数据
     * 目录
     *
     * @参数aContext
     *:应用程序上下文
     * @参数DATABASENAME
     *:数据库名称
     * @返回:完整路径
     * /
    私有静态字符串getDatabasePath(上下文aContext,串DATABASENAME){
            返回DB_PATH_ preFIX + aContext.getPackageName()+ DB_PATH_SUFFIX
                            + DATABASENAME;
    }

    公共布尔的executeQuery(字符串tableName值,字符串键,字符串值){
        返回的ExecQuery(tableName值,键,值);
    }

    私有静态布尔的ExecQuery(字符串tableName值,字符串键,字符串值){
        sqliteDb = instance.getWritableDatabase();
        ContentValues​​值=新ContentValues​​();
        values​​.put(键,值);
        sqliteDb.insert(tableName值,空,价值观);

        返回true;

    }

    公共布尔即updateSQL(字符串tableName值,字符串键,字符串值){
        返回了updateData(tableName值,键,值);
    }

    私有静态布尔了updateData(字符串tableName值,字符串键,字符串值){
        sqliteDb = instance.getWritableDatabase();
        字符串,其中=code_ID =?;
        ContentValues​​值=新ContentValues​​();
        values​​.put(键,值);
        values​​.put(键,值);
        sqliteDb.update(tableName值,值,其中,新的String [] {3});
        返回true;
    }

    公共布尔deleteSQL(字符串tableName值){
        返回deleteData(tableName值);
    }

    私有静态布尔deleteData(字符串tableName值){
        sqliteDb = instance.getWritableDatabase();
        字符串,其中=code_ID =?;
        sqliteDb.delete(tableName值,其中,新的String [] {5});
        返回true;
    }

    公共光标executeSQLQuery(查询字符串){
        返回sqliteDb.rawQuery(查询,NULL);
    }

}
 

我的问题是:我怎么能初始化数据库只有一次,可以从我的所有活动的机会呢? (提示:我在资产的文件夹,我复制到我的系统数据库文件夹有sqlite的文件时,应用程序星级)

在此先感谢!

编辑:我忘了说,我在我的应用2种不同的SQLite数据库,我希望能够初始化二者为整个应用程序,并可以使用了进来的东西,我试图做的:

  DataBaseHelper dbHelper;
//一些code
dbHelper =新DataBaseHelper(上下文中,ops_sys_tpl.sqlite,空,1);
        DataBaseHelper.initialize(上下文中,stampii_sys_tpl.sqlite);

        dbHelper.copyDataBase(ops_sys_tpl.sqlite);

        dbHelper.getDatabase();
        dbHelper.executeQuery(用户,的ObjectID,2);
        dbHelper.executeQuery(用户,的serverName,stampii);
        dbHelper.executeQuery(用户,的ObjectID,3);
        dbHelper.executeQuery(用户,的serverName,stampii);
        dbHelper.executeQuery(用户,的ObjectID,3);
 

解决方案

创建您的实例只有一次这样,同code,你可以添加在数据库处理程序类,但我preFER以保持其独立的。

 公共类MyTestDatabaseInstanceHolder {

    公共MyTestDBHandler DBHelper;
    公共静态SQLiteDatabase m_ObjDataBase; //这是跨应用程序了访问全局变量

    公共静态无效createDBInstance(上下文pContext){
        如果(DBHelper == NULL){
            DBHelper =新WLDBHandler(pContext); //这将是你的数据库处理类
            m_cObjDataBase = DBHelper.openAndCreateDataBase(); // Initialze数据库注:openAndCreateDataBase是您创建做的一切的回报数据库对象的实用方法
        }
      }
}
 

在您的入口点(闪屏)称这样的:

  MyTestDatabaseInstanceHolder.createDBInstance(getApplicationContext());
 

用法 - 一些其他类:

  MyTestDatabaseInstanceHolder.m_ObjDataBase.rawQuery( - );
 

I have a custom DataBaseHelper class which extends SQLiteOpenHelper,which looks like this :

package com.stampii.stampii.comm.rpc;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.ResultSet;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DataBaseHelper extends SQLiteOpenHelper{

    private static SQLiteDatabase sqliteDb;
    private static DataBaseHelper instance;
    private static final int DATABASE_VERSION = 1;
    // the default database path is :
    // /data/data/pkgNameOfYourApplication/databases/
    private static String DB_PATH_PREFIX = "/data/data/";
    private static String DB_PATH_SUFFIX = "/databases/";
    private static final String TAG = "DataBaseHelper";
    private Context context;

    /***
     * Contructor
     * 
     * @param context
     *            : app context
     * @param name
     *            : database name
     * @param factory
     *            : cursor Factory
     * @param version
     *            : DB version
     */
    public DataBaseHelper(Context context, String name,
                    CursorFactory factory, int version) {
            super(context, name, factory, version);
            this.context = context;
            Log.i(TAG, "Create or Open database : " + name);
    }

    /***
     * Initialize method
     * 
     * @param context
     *            : application context
     * @param databaseName
     *            : database name
     */
    public static  void initialize(Context context, String databaseName) {
            if (instance == null) {
                    /**
                     * Try to check if there is an Original copy of DB in asset
                     * Directory
                     */
                    if (!checkDatabase(context, databaseName)) {
                            // if not exists, I try to copy from asset dir
                            try {
                                copyDataBase(context, databaseName);
                            } catch (IOException e) {
                                    Log.e(TAG,"Database "+ databaseName+" does not exists and there is no Original Version in Asset dir");
                            }
                    }

                    Log.i(TAG, "Try to create instance of database (" + databaseName
                                    + ")");
                    instance = new DataBaseHelper(context, databaseName,
                                    null, DATABASE_VERSION);
                    sqliteDb = instance.getWritableDatabase();
                    Log.i(TAG, "instance of database (" + databaseName + ") created !");
            }
    }

    /***
     * Static method for getting singleton instance
     * 
     * @param context
     *            : application context
     * @param databaseName
     *            : database name
     * @return : singleton instance
     */
    public static final DataBaseHelper getInstance(
                    Context context, String databaseName) {
            initialize(context, databaseName);
            return instance;
    }

    /***
     * Method to get database instance
     * 
     * @return database instance
     */
    public SQLiteDatabase getDatabase() {
            return sqliteDb;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
            Log.d(TAG, "onCreate : nothing to do");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.d(TAG, "onUpgrade : nothing to do");

    }

    /***
     * Method for Copy the database from asset directory to application's data
     * directory
     * 
     * @param databaseName
     *            : database name
     * @throws IOException
     *             : exception if file does not exists
     */
    public void copyDataBase(String databaseName) throws IOException {
            copyDataBase(context, databaseName);
    }

    /***
     * Static method for copy the database from asset directory to application's
     * data directory
     * 
     * @param aContext
     *            : application context
     * @param databaseName
     *            : database name
     * @throws IOException
     *             : exception if file does not exists
     */
    private static void copyDataBase(Context aContext, String databaseName)
                    throws IOException {

            // Open your local db as the input stream
            InputStream myInput = aContext.getAssets().open(databaseName);

            // Path to the just created empty db
            String outFileName = getDatabasePath(aContext, databaseName);

            Log.i(TAG, "Check if create dir : " + DB_PATH_PREFIX
                            + aContext.getPackageName() + DB_PATH_SUFFIX);

            // if the path doesn't exist first, create it
            File f = new File(DB_PATH_PREFIX + aContext.getPackageName()
                            + DB_PATH_SUFFIX);
            if (!f.exists())
                    f.mkdir();

            Log.i(TAG, "Trying to copy local DB to : " + outFileName);

            // Open the empty db as the output stream
            OutputStream myOutput = new FileOutputStream(outFileName);

            // transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                    myOutput.write(buffer, 0, length);
            }

            // Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();

            Log.i(TAG, "DB (" + databaseName + ") copied!");
    }

    /***
     * Method to check if database exists in application's data directory
     * 
     * @param databaseName
     *            : database name
     * @return : boolean (true if exists)
     */
    public boolean checkDatabase(String databaseName) {
            return checkDatabase(context, databaseName);
    }

    /***
     * Static Method to check if database exists in application's data directory
     * 
     * @param aContext
     *            : application context
     * @param databaseName
     *            : database name
     * @return : boolean (true if exists)
     */
    private static boolean checkDatabase(Context aContext, String databaseName) {
            SQLiteDatabase checkDB = null;

            try {
                    String myPath = getDatabasePath(aContext, databaseName);

                    Log.i(TAG, "Trying to conntect to : " + myPath);
                    checkDB = SQLiteDatabase.openDatabase(myPath, null,
                                    SQLiteDatabase.OPEN_READONLY);
                    Log.i(TAG, "Database " + databaseName + " found!");
                    checkDB.close();
            } catch (SQLiteException e) {
                    Log.i(TAG, "Database " + databaseName + " does not exists!");

            }

            return checkDB != null ? true : false;
    }

    /***
     * Method that returns database path in the application's data directory
     * 
     * @param databaseName
     *            : database name
     * @return : complete path
     */
    private String getDatabasePath(final String databaseName) {
            return getDatabasePath(context, databaseName);
    }

    /***
     * Static Method that returns database path in the application's data
     * directory
     * 
     * @param aContext
     *            : application context
     * @param databaseName
     *            : database name
     * @return : complete path
     */
    private static String getDatabasePath(Context aContext, String databaseName) {
            return DB_PATH_PREFIX + aContext.getPackageName() + DB_PATH_SUFFIX
                            + databaseName;
    }

    public boolean executeQuery(String tableName,String keys,String value){
        return execQuery(tableName,keys,value);
    }

    private static boolean execQuery(String tableName,String key,String value){
        sqliteDb = instance.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(key, value);
        sqliteDb.insert(tableName, null, values);

        return true;

    }

    public boolean updateSQL(String tableName,String key,String value){
        return updateData(tableName,key,value); 
    }

    private static boolean updateData(String tableName,String key,String value){
        sqliteDb = instance.getWritableDatabase();
        String where = "code_id=?";
        ContentValues values = new ContentValues();
        values.put(key, value);
        values.put(key, value);
        sqliteDb.update(tableName, values, where, new String[] {"3"});
        return true;
    }

    public boolean deleteSQL(String tableName){
        return deleteData(tableName);
    }

    private static boolean deleteData(String tableName){
        sqliteDb = instance.getWritableDatabase();
        String where = "code_id=?";
        sqliteDb.delete(tableName, where, new String[] {"5"});
        return true;
    }

    public Cursor executeSQLQuery(String query){
        return sqliteDb.rawQuery(query,null);
    }

}

My question is : How can I initialize the database only once and can access it from all my Activities? (Hint: I have sqlite files in my assets folder,which I copy to my system database folder when the app stars.)

Thanks in advance!

EDIT : I forgot to say that I have 2 different sqlite databases in my application and I want to be able to initialize both of them for the whole application and can use them.That's something that I was trying to do :

DataBaseHelper dbHelper;
//some code
dbHelper = new DataBaseHelper(context, "ops_sys_tpl.sqlite", null, 1);
        DataBaseHelper.initialize(context, "stampii_sys_tpl.sqlite");

        dbHelper.copyDataBase("ops_sys_tpl.sqlite");

        dbHelper.getDatabase();
        dbHelper.executeQuery("users", "objectId", "2");
        dbHelper.executeQuery("users","serverName","stampii");
        dbHelper.executeQuery("users", "objectId", "3");
        dbHelper.executeQuery("users","serverName","stampii");
        dbHelper.executeQuery("users", "objectId", "3");

解决方案

Create your instance only once like this, The same code you can add in DB handler class but I prefer to keep it seperate.

public class MyTestDatabaseInstanceHolder {

    public MyTestDBHandler DBHelper;  
    public static SQLiteDatabase m_ObjDataBase; // This is global variable to access across the applicaiton

    public static void createDBInstance(Context pContext){
        if(DBHelper == null) {
            DBHelper = new WLDBHandler(pContext); // This will be your DB Handler Class
            m_cObjDataBase = DBHelper.openAndCreateDataBase(); // Initialze the DB Note: openAndCreateDataBase is a utility method created by you to do everything an return the DB object
        }
      }
}

In your entry point (Splash Screen) call this:

MyTestDatabaseInstanceHolder.createDBInstance(getApplicationContext());

Usage - Some other Class:

MyTestDatabaseInstanceHolder.m_ObjDataBase.rawQuery(---);

这篇关于如何从Android的一个辅助类初始化SQLite数据库一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆