首次调用SQLiteCursor的getCount 需要锁定数据库

Posted siwnchh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了首次调用SQLiteCursor的getCount 需要锁定数据库相关的知识,希望对你有一定的参考价值。

当我们第一调用android.database.sqlite.SQLiteCursorgetCount()时,当前线程会锁定数据库,在该操作完成后才解锁。
其调用关系如下
at android.database.sqlite.SQLiteQuery.native_fill_window(Native Method) 
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:73) 
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:287) 
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:268) 
at android.widget.CursorAdapter.getCount(CursorAdapter.java:132) 
如果是第一次调用SQLiteCursorgetCount()的话,在getCount()中,它会调用fillWindow(),
在SQLiteCursor的fillWindow()中,它又会调用SQLiteQueryfillWindow()
android.database.sqlite.SQLiteCursor的相关源码如下:
@Override
    public int getCount() {
        if (mCount == NO_COUNT) {
            fillWindow(0);
        }
        return mCount;
    }
 
    private void fillWindow (int startPos) {
        if (mWindow == null) {
            // If there isn‘t a window set already it will only be accessed locally
            mWindow = new CursorWindow(true /* the window is local only */);
        } else {
            mCursorState++;
                queryThreadLock();
                try {
                    mWindow.clear();
                } finally {
                    queryThreadUnlock();
                }
        }
        mWindow.setStartPosition(startPos);
        mCount = mQuery.fillWindow(mWindow, mInitialRead, 0);
        // return -1 means not finished
        if (mCount == NO_COUNT){
            mCount = startPos + mInitialRead;
            Thread t = new Thread(new QueryThread(mCursorState), "query thread");
            t.start();
        } 
    }
SQLiteQueryfillWindow()中,它首先需要lock数据库,然后调用JNI层的native_fill_window()进行数据库操作,在其操作完成之后才unlock数据库
android.database.sqlite.SQLiteQuery的相关源码如下:
/**
     * Reads rows into a buffer. This method acquires the database lock.
     *
     * @param window The window to fill into
     * @return number of total rows in the query
     */
   int fillWindow(CursorWindow window,
            int maxRead, int lastPos) {
        long timeStart = SystemClock.uptimeMillis();
        mDatabase.lock();
        mDatabase.logTimeStat(mSql, timeStart, SQLiteDatabase.GET_LOCK_LOG_PREFIX);
        try {
            acquireReference();
            try {
                window.acquireReference();
                // if the start pos is not equal to 0, then most likely window is
                // too small for the data set, loading by another thread
                // is not safe in this situation. the native code will ignore maxRead
                int numRows = native_fill_window(window, window.getStartPosition(), mOffsetIndex,
                        maxRead, lastPos);
 
                // Logging
                if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
                    Log.d(TAG, "fillWindow(): " + mSql);
                }
                mDatabase.logTimeStat(mSql, timeStart);
                return numRows;
            } catch (IllegalStateException e){
                // simply ignore it
                return 0;
            } catch (SQLiteDatabaseCorruptException e) {
                mDatabase.onCorruption();
                throw e;
            } finally {
                window.releaseReference();
            }
        } finally {
            releaseReference();
            mDatabase.unlock();
        }
    }
 
结束!

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net

以上是关于首次调用SQLiteCursor的getCount 需要锁定数据库的主要内容,如果未能解决你的问题,请参考以下文章

Adapter

2.5 ListView

Mongo Java 驱动程序 ObjectId.getCounter() 已弃用

商店上的 extjs 组合框 getCount() 返回 0

使用 cursor.getCount() 获取计数或在 SQL 子句上使用 COUNT 执行 rawQuery?

Java Android - 自定义适配器 getCount 方法 nullPointer 错误