SQLiteOpenHelper/SQLiteDatabase/Cursor源码解析

转载请注明出处:http://blog.csdn.net/y_zhiwen/article/details/51583188

Github地址,欢迎star和follow

新增android sqlite native 的代码

我们在使用android提供的SQLite存储数据的时候,就会用到SQLiteOpenHelper和SQLiteDataBase,但查询数据的时候会得到一个Cursor对象,这里我们将深入android提供的关于SQLite的封装以原理。

SQLiteOpenHelper

——封装管理数据库的创造和版本管理类

主要封装了数据库的创建和获取的方法,一般继承该类实现onCreate()、onUpdate()方法,在onCreate创建数据库,在onUpdate进行数据库升级操作。其中还有onConfigure()、onDowngrade()、onOpen()方法,将会在下面获取数据库对象分析进行解析

  • 数据库的获取:
    两个方法:getReadableDatabase()、getWritableDatabase()。需要注意的一点是这两个方法都加锁,是线程安全的。这两个方法最终调用getDatabaseLocked(boolean writable):
private SQLiteDatabase getDatabaseLocked(boolean writable) {
    if (mDatabase != null) {

        if (!mDatabase.isOpen()) {  // 判断数据库是否已经关闭
            // Darn!  The user closed the database by calling mDatabase.close().
            mDatabase = null;
        } else if (!writable || !mDatabase.isReadOnly()) { //判断数据库是否符合要求,如果数据库可读可写则返回,即!mDatabase.isReadOnly()一直为true
            // The database is already open for business.
            return mDatabase;
        }
    }

    // 正在初始化中
    if (mIsInitializing) {
        throw new IllegalStateException("getDatabase called recursively");
    }

    SQLiteDatabase db = mDatabase;
    try {
        mIsInitializing = true;

        if (db != null) { // 数据库不为null,需要重新开启读写数据库使得符合要求
            if (writable && db.isReadOnly()) {
                db.reopenReadWrite();
            }
        } else if (mName == null) {
            db = SQLiteDatabase.create(null);
        } else {
            try {
                if (DEBUG_STRICT_READONLY && !writable) {
                    final String path = mContext.getDatabasePath(mName).getPath();
                    db = SQLiteDatabase.openDatabase(path, mFactory,
                            SQLiteDatabase.OPEN_READONLY, mErrorHandler);
                } else {
                    // 通过mContext.openOrCreateDatabase创建数据库,其实还是调用SQLiteDatabase.openDatabase(..)创建数据库
                    db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
                            Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
                            mFactory, mErrorHandler);
                }
            } catch (SQLiteException ex) {
                if (writable) {
                    throw ex;
                }
                Log.e(TAG, "Couldn't open " + mName
                        + " for writing (will try read-only):", ex);
                final String path = mContext.getDatabasePath(mName).getPath();
                db = SQLiteDatabase.openDatabase(path, mFactory,
                        SQLiteDatabase.OPEN_READONLY, mErrorHandler);
            }
        }

        // 调用onConfigure
        onConfigure(db);

        final int version = db.getVersion();
        if (version != mNewVersion) {
            if (db.isReadOnly()) {
                throw new SQLiteException("Can't upgrade read-only database from version " +
                        db.getVersion() + " to " + mNewVersion + ": " + mName);
            }

            db.beginTransaction();
            try {
                // 当第一次创建数据库时DataBase的版本为0,会调用onCreate()方法
                if (version == 0) {
                    onCreate(db);
                } else {  // 判断数据库版本升降级,调用相应方法
                    if (version > mNewVersion) {
                        onDowngrade(db, version, mNewVersion);
                    } else {
                        onUpgrade(db, version, mNewVersion);
                    }
                }
                db.setVersion(mNewVersion);
                db.setTransactionSuccessful();
            } finally {
                db.endTransaction();
            }
        }

        // 调用onOpen()方法
        onOpen(db);

        if (db.isReadOnly()) {
            Log.w(TAG, "Opened " + mName + " in read-only mode");
        }

        mDatabase = d
  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值