首次調用SQLiteCursor的getCount()需要鎖定資料庫

來源:互聯網
上載者:User

當我們第一調用android.database.sqlite.SQLiteCursor的getCount()時,當前線程會鎖定資料庫,在該操作完成後才解鎖。其調用關係如下: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) 如果是第一次調用SQLiteCursor的getCount()的話,在getCount()中,它會調用fillWindow(),在SQLiteCursor的fillWindow()中,它又會調用SQLiteQuery的fillWindow()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();        }     }

在SQLiteQuery的fillWindow()中,它首先需要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();        }    }


結束!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.