当前位置:首页 > 数据库 > 正文

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

当我们第一调用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