2727import java .io .FileOutputStream ;
2828import java .io .IOException ;
2929import java .io .OutputStream ;
30- import java .lang .ref .WeakReference ;
3130import java .text .SimpleDateFormat ;
3231import java .util .ArrayList ;
3332import java .util .HashMap ;
@@ -73,6 +72,12 @@ public class SQLiteDatabase extends SQLiteClosable {
7372 private static final int EVENT_DB_OPERATION = 52000 ;
7473 private static final int EVENT_DB_CORRUPT = 75004 ;
7574
75+ // Stores reference to all databases opened in the current process.
76+ // (The referent Object is not used at this time.)
77+ // INVARIANT: Guarded by sActiveDatabases.
78+ private static WeakHashMap <SQLiteDatabase , Object > sActiveDatabases =
79+ new WeakHashMap <SQLiteDatabase , Object >();
80+
7681 public int status (int operation , boolean reset ){
7782 return native_status (operation , reset );
7883 }
@@ -394,6 +399,10 @@ protected void onAllReferencesReleased() {
394399 mTimeClosed = getTime ();
395400 }
396401 dbclose ();
402+
403+ synchronized (sActiveDatabases ) {
404+ sActiveDatabases .remove (this );
405+ }
397406 }
398407 }
399408
@@ -958,6 +967,7 @@ public static SQLiteDatabase openDatabase(String path, String password, CursorFa
958967 */
959968 public static SQLiteDatabase openDatabase (String path , char [] password , CursorFactory factory , int flags , SQLiteDatabaseHook hook ) {
960969 SQLiteDatabase sqliteDatabase = null ;
970+
961971 try {
962972 // Open the database.
963973 sqliteDatabase = new SQLiteDatabase (path , password , factory , flags , hook );
@@ -978,7 +988,10 @@ public static SQLiteDatabase openDatabase(String path, char[] password, CursorFa
978988 }
979989 sqliteDatabase = new SQLiteDatabase (path , password , factory , flags , hook );
980990 }
981- ActiveDatabases .getInstance ().mActiveDatabases .add (new WeakReference <SQLiteDatabase >(sqliteDatabase ));
991+
992+ synchronized (sActiveDatabases ) {
993+ sActiveDatabases .put (sqliteDatabase , null );
994+ }
982995 return sqliteDatabase ;
983996 }
984997
@@ -2335,25 +2348,18 @@ public synchronized void setMaxSqlCacheSize(int cacheSize) {
23352348 mMaxSqlCacheSize = cacheSize ;
23362349 }
23372350
2338- static class ActiveDatabases {
2339- private static final ActiveDatabases activeDatabases = new ActiveDatabases ();
2340- private HashSet <WeakReference <SQLiteDatabase >> mActiveDatabases =
2341- new HashSet <WeakReference <SQLiteDatabase >>();
2342- private ActiveDatabases () {} // disable instantiation of this class
2343- static ActiveDatabases getInstance () {return activeDatabases ;}
2344- }
2345-
23462351 /**
23472352 * this method is used to collect data about ALL open databases in the current process.
23482353 * bugreport is a user of this data.
23492354 */
23502355 /* package */ static ArrayList <DbStats > getDbStats () {
23512356 ArrayList <DbStats > dbStatsList = new ArrayList <DbStats >();
2352- for ( WeakReference < SQLiteDatabase > w : ActiveDatabases . getInstance (). mActiveDatabases ) {
2353- SQLiteDatabase db = w . get ();
2357+
2358+ for ( SQLiteDatabase db : getActiveDatabases ()) {
23542359 if (db == null || !db .isOpen ()) {
23552360 continue ;
23562361 }
2362+
23572363 // get SQLITE_DBSTATUS_LOOKASIDE_USED for the db
23582364 int lookasideUsed = db .native_getDbLookaside ();
23592365
@@ -2395,6 +2401,14 @@ private ActiveDatabases() {} // disable instantiation of this class
23952401 return dbStatsList ;
23962402 }
23972403
2404+ private static ArrayList <SQLiteDatabase > getActiveDatabases () {
2405+ ArrayList <SQLiteDatabase > databases = new ArrayList <SQLiteDatabase >();
2406+ synchronized (sActiveDatabases ) {
2407+ databases .addAll (sActiveDatabases .keySet ());
2408+ }
2409+ return databases ;
2410+ }
2411+
23982412 /**
23992413 * get the specified pragma value from sqlite for the specified database.
24002414 * only handles pragma's that return int/long.
0 commit comments