当我们第一调用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(); } } 结束!
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net