2 回答

TA貢獻1829條經驗 獲得超4個贊
簡而言之,如果您使用正確的技術,但如果您使用歷史上經常使用的方法,則不需要,如下所示,那么您必須這樣做,因為:-
this.getReadableDatabase()
使用/已經使用的原因是在 data/data/the_package/ 目錄中創建數據庫文件夾/目錄。如果數據庫目錄不存在,則來自資產的典型副本將失敗并出現 ENOENT 錯誤。
SQLite 默認使用日志模式日志記錄,這不是問題,因此歷史上 using的繞過方法this.getReadableDatabase()
一直有效。
但是,在 Android Pie (28) 中,SDK 已更改為默認使用預寫日志記錄 (WAL),這是一種較晚且更高級的日志記錄方法。此方法使用兩個已改進安全措施的文件。一個是文件被標記/標記為屬于創建它們的數據庫。
因此,當使用沒有關閉的舊方法復制數據庫時,這兩個文件(數據庫文件以 -wal 和 -shm 為后綴)存在并且很可能包含日志記錄數據(例如任何表的創建)。但是,它們不會被標記為用于復制的數據庫,因此(我相信)重新創建數據庫(因為復制的數據庫由于數據庫與 -shm 和 -wal 文件不匹配而無法打開)因此隨后的表未找到通常會遇到的錯誤。
使用 WAL 關閉數據庫/連接會導致數據被提交,因此為什么在this.getReadableDatabase()
工作后(立即)關閉數據庫。
但是,正確的解決方法是使用 File 方法檢查并創建數據庫目錄(如果它不存在)。這樣就不需要打開數據庫,這會浪費資源,也不需要關閉數據庫,這也會浪費資源(即實際執行記錄的操作并將數據寫入磁盤和 -wal 和-shm 文件也被讀取和重寫)。

TA貢獻1798條經驗 獲得超7個贊
我認為這個問題是由于每個 Android 版本都帶來了不同的 SQLite 版本,并且一些供應商也自定義了 SQLite 庫版本。正如您可以從此鏈接中閱讀的那樣:
Android API SQLite Version
API 27 3.19
API 26 3.18
API 24 3.9
API 21 3.8
API 11 3.7
API 8 3.6
API 3 3.5
API 1 3.4
希望能幫助到你。
添加回答
舉報