实现SQLite Manager以进行线程安全的读/写访问?

时间:2011-04-26 05:10:38

标签: android

我正在计划改进我的SQLite实现 - 目前,活动是在需要一些相关数据时打开SQLite DB,然后关闭它。关闭数据库对于避免异常很重要。

我的设计目标:

  1. 对应用程序的SQLite DB进行线程安全访问

  2. 同步操作

  3. 我认为我会做的是实现某种“经理”类而不是我的基本“SQLhelper”类。我想要同步操作,以便排除将其实现为带有消息的服务。

    我认为实现这个“SQLiteManager”的最佳方式是单例。

    有没有更好的实施?

1 个答案:

答案 0 :(得分:10)

第1步 - 扩展Application类

import android.app.Application;
import android.content.Context;

/**
 * This class is created automatically when the app launches.
 * It is used to provide an application-level context for the SQLiteOpenHelper
 */
public class ApplicationContext extends Application
{

    private static ApplicationContext instance;

    public ApplicationContext()
    {
        instance = this;
    }

    public static Context getContext()
    {
        return instance;
    }

}

第2步 - 更新清单以便使用此应用程序类

<application android:name="ApplicationContext"
             android:icon="@drawable/icon" 
             android:label="@string/app_name"
             android:debuggable="true">

第3步 - 在您的应用中构建单例SQLdataHelper

public class SQLdataHelper
{
    //for logging
    private final String TAG = this.getClass().getSimpleName();

    //DATABASE
    private static final String DATABASE_NAME = "my.db";
    private static final int DATABASE_VERSION = 1;//initial version

    //TABLE NAMES
    private static final String TABLE_NAME_A = "exampleOneTable";

    //MEMBER VARIABLES
    private DatabaseHelper mDBhelper;
    private SQLiteDatabase mDB;

    //SINGLETON
    private static final SQLdataHelper instance = new SQLdataHelper();


    private SQLdataHelper()
    {
        final DatabaseHelper dbHelper = new DatabaseHelper(ApplicationContext.getContext());

        //open the DB for read and write
        mDB = dbHelper.getWritableDatabase();
    }


    public static SQLdataHelper getInstance()
    {
        return instance;
    }

    /**
     *  INSERT FUNCTIONS consisting of "synchronized" methods 
     */
    public synchronized long insertTableA(String myName, int myAge)
    {
        Long lValueToReturn;

        //organize the data to store as key/value pairs
        ContentValues kvPairs = new ContentValues();
        kvPairs.put("ColumnOne", myName);
        kvPairs.put("ColumnTwo", myAge);

        lValueToReturn = mDB.insert(TABLE_NAME_A, null, kvPairs);

        return lValueToReturn;
    }


    private static class DatabaseHelper extends SQLiteOpenHelper
    {

        DatabaseHelper(Context context)
        {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }


        //this is called for first time db is created.
        // put all CREATE TABLE here
        @Override
        public void onCreate(SQLiteDatabase db)
        {
            db.execSQL( "CREATE TABLE "
                       + TABLE_NAME_A 
                       + " ("
                       + "_id INTEGER PRIMARY KEY AUTOINCREMENT,"
                       + "ColumnOne TEXT,"
                       + "ColumnTwo TEXT"
                       + ")" );
        }

        //this is called when an existing user updates to a newer version of the app
        // add CREATE TABLE and ALTER TABLE here
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
        {

            //update SQL DB with new columns depending on old version
            // also add new tables
            //NOTE: whatever is done here must also go into onCreate() so that new users get the correct db created
            switch(oldVersion)
            {
            case 1:
//EXAMPLE         db.execSQL("ALTER TABLE " + TABLE_NAME_A + " ADD COLUMN ColumnThree INTEGER;");

                 //don't use a break. for next case simply let them run together to update all the way to latest version
                 //This way, the case just represents a starting point to start updating.

            case 2:
//EXAMPLE         db.execSQL("ALTER TABLE " + TABLE_NAME_A + " ADD COLUMN ColumnFour INTEGER;");

            }

//this code drops the table and will create a fresh one. Note all data lost!
//          db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME_C);
//          onCreate(db);
        }

    }

}

我只包含一个示例插入操作。根据需要添加更多,并确保它们是“同步”方法。

第4步 - 在您的活动中使用SQLdataHelper

    SQLdataHelper mDataHelper = SQLdataHelper.getInstance();
    mDataHelper.insertTableA("Someone", 100);