度々お世話になります。Androidアプリ開発の初心者です。
Microsoft Learn等のサイトを参考に、見様見真似で販売管理ツールを組んでいます。
■やりたいこと
SQL Serverから、Androidスマート端末内SqLite DBに、データをインポートします。
その前に、端末内DBファイルを削除したいのです。
それから、
・Drop Table if exists
・Create Table if not exists
・Insert Into
・……
という具合にデータのインポート処理しています。
■問題点
前述のインポート処理前に、Java.IO.Fileにて File.Delete() を実行。SqLite DBファイルを削除。
ここで一旦アプリを終了し、再起動すると、前述のインポート処理は上手くいきます(色々試してみて判明。つまり単純なソース記述ミスではない)
ところがSqLite DBファイルを削除した後、(アプリを終了させず)続けてインポート処理を行おうとすると、「Disk I/O Error」が発生し処理が通りません。
色々試してみたのですが、「Attempt to write for read only database~」(ちょっとうろ覚え)というエラーが発生。或いは「Database is locked」の時もありました。要するにDBに書き込めないためエラーが発生しているようです。
■開発環境等
Xamarin.Androidプロジェクト
最小Android 9.0(API28) ~ ターゲットAndroid 11.0(API30)
Win11 Pro + Visual Studio 2019(開発環境)
Android9タブレット端末 / Android11スマート端末(デバッグ用端末)
DBはそれぞれにプリインストールされているSqLite
using Microsoft.Data.Sqlite
■試してみたこと
DBファイル削除に時間がかかっているのかも、とDelayを最大1分実行し、それからインポート処理続行。NGでした。
先に明示的にSqLite Connectionをクローズしてから削除するも、NG。
Activityを再起動してからインポート処理実行。→NG。
SqLite ConnectionをオープンしてからDelayを措いてみた。→NG。
Journalモード/WALモードの指定。→NG。
(再起動後ならモード変更を受け付けてくれるが、DBファイル削除直後だとNG)
■削除処理ソース
C#
1public void RemoveDbFile() 2 { 3 Java.IO.File _file = new File(Definitions.DbPath); 4 _file.Delete(); 5 6 // 念のため関連ファイルも削除 7 _file = new File(Definitions.DbPath + "-journal"); 8 _file.Delete(); 9 10 _file = new File(Definitions.DbPath + "-shm"); 11 _file.Delete(); 12 13 _file = new File(Definitions.DbPath + "-wal"); 14 _file.Delete(); 15 }
■教えて頂きたいこと
なぜ、DBファイル削除後に一旦アプリを終了させればOKなのか。
なぜ、DBファイル削除に続けて処理実行すると、(ソースコードは同一なのに)DBに書き込めないのか。
まずはそこが謎です。何が原因なのでしょうか。
SqLiteのDB削除は、DBファイルを削除すればよいだけだ、という記述をWeb上にてよく見かけます。
ですが、実際はそれだけではダメなのでしょうか。
Androidの仕組み上、何らかのコツがあるのでしょうか。
SqLiteのDBファイルは、フルパスの名称さえ指定してコネクションをオープンすれば、ファイルが存在しなくても勝手に作成される、とMicrosoft Learnに記述があります。
ですが、実際はそれだけではダメなのでしょうか。
Androidの仕組み上、何らかのコツがあるのでしょうか。
或いは削除前にトランザクションを破棄しておくだとか、DBファイルが作成された直後に何らかのDB設定コマンドを送信しておくべきなのでしょうか。要するに削除前なり削除後なりに、何か処理が必要なのでしょうか。
以上、何でも結構ですので、対処の取っ掛かりとなるようなナレッジがあればご教示頂きたいと思います。
Android Studioでの開発における、類似の問題の対処法でも構いません。
よろしくお願い致します。

回答1件
あなたの回答
tips
プレビュー