Android getReadableDatabase() 和 getWritableDatabase()

时间:2023-03-08 22:06:34
Android getReadableDatabase() 和 getWritableDatabase()

Android使用getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。(getReadableDatabase()方法中会调用getWritableDatabase()方法)

其中getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用的是getWritableDatabase() 方法就会出错。

getReadableDatabase()方法则是先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。如果该问题成功解决,则只读数据库对象就会关闭,然后返回一个可读写的数据库对象。

源码如下:

  1. /**
  2. * Create and/or open a database that will be used for reading and writing.
  3. * Once opened successfully, the database is cached, so you can call this
  4. * method every time you need to write to the database.  Make sure to call
  5. * {@link #close} when you no longer need it.
  6. *
  7. * <p>Errors such as bad permissions or a full disk may cause this operation
  8. * to fail, but future attempts may succeed if the problem is fixed.</p>
  9. *
  10. * @throws SQLiteException if the database cannot be opened for writing
  11. * @return a read/write database object valid until {@link #close} is called
  12. */
  13. public synchronized SQLiteDatabase getWritableDatabase() {
  14. if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
  15. return mDatabase;  // The database is already open for business
  16. }
  17. if (mIsInitializing) {
  18. throw new IllegalStateException("getWritableDatabase called recursively");
  19. }
  20. // If we have a read-only database open, someone could be using it
  21. // (though they shouldn't), which would cause a lock to be held on
  22. // the file, and our attempts to open the database read-write would
  23. // fail waiting for the file lock.  To prevent that, we acquire the
  24. // lock on the read-only database, which shuts out other users.
  25. boolean success = false;
  26. SQLiteDatabase db = null;
  27. if (mDatabase != null) mDatabase.lock();
  28. try {
  29. mIsInitializing = true;
  30. if (mName == null) {
  31. db = SQLiteDatabase.create(null);
  32. } else {
  33. db = mContext.openOrCreateDatabase(mName, 0, mFactory);
  34. }
  35. int version = db.getVersion();
  36. if (version != mNewVersion) {
  37. db.beginTransaction();
  38. try {
  39. if (version == 0) {
  40. onCreate(db);
  41. } else {
  42. onUpgrade(db, version, mNewVersion);
  43. }
  44. db.setVersion(mNewVersion);
  45. db.setTransactionSuccessful();
  46. } finally {
  47. db.endTransaction();
  48. }
  49. }
  50. onOpen(db);
  51. success = true;
  52. return db;
  53. } finally {
  54. mIsInitializing = false;
  55. if (success) {
  56. if (mDatabase != null) {
  57. try { mDatabase.close(); } catch (Exception e) { }
  58. mDatabase.unlock();
  59. }
  60. mDatabase = db;
  61. } else {
  62. if (mDatabase != null) mDatabase.unlock();
  63. if (db != null) db.close();
  64. }
  65. }
  66. }
  67. /**
  68. * Create and/or open a database.  This will be the same object returned by
  69. * {@link #getWritableDatabase} unless some problem, such as a full disk,
  70. * requires the database to be opened read-only.  In that case, a read-only
  71. * database object will be returned.  If the problem is fixed, a future call
  72. * to {@link #getWritableDatabase} may succeed, in which case the read-only
  73. * database object will be closed and the read/write object will be returned
  74. * in the future.
  75. *
  76. * @throws SQLiteException if the database cannot be opened
  77. * @return a database object valid until {@link #getWritableDatabase}
  78. *     or {@link #close} is called.
  79. */
  80. public synchronized SQLiteDatabase getReadableDatabase() {
  81. if (mDatabase != null && mDatabase.isOpen()) {
  82. return mDatabase;  // The database is already open for business
  83. }
  84. if (mIsInitializing) {
  85. throw new IllegalStateException("getReadableDatabase called recursively");
  86. }
  87. try {
  88. return getWritableDatabase();
  89. } catch (SQLiteException e) {
  90. if (mName == null) throw e;  // Can't open a temp database read-only!
  91. Log.e(TAG, "Couldn't open " + mName + " for writing (will try read-only):", e);
  92. }
  93. SQLiteDatabase db = null;
  94. try {
  95. mIsInitializing = true;
  96. String path = mContext.getDatabasePath(mName).getPath();
  97. db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY);
  98. if (db.getVersion() != mNewVersion) {
  99. throw new SQLiteException("Can't upgrade read-only database from version " +
  100. db.getVersion() + " to " + mNewVersion + ": " + path);
  101. }
  102. onOpen(db);
  103. Log.w(TAG, "Opened " + mName + " in read-only mode");
  104. mDatabase = db;
  105. return mDatabase;
  106. } finally {
  107. mIsInitializing = false;
  108. if (db != null && db != mDatabase) db.close();
  109. }
  110. }