##はじめに
Android初心者です。
テキストやWebページを見ながら EditText の値をデータベースに登録できるようになったのですが、連続入力しようとすると落ちてしまう。
アプリを1回開く度1回しかデータを登録できない!
これはアプリとして致命的だと思いどうしたら良いのか調べました。
要因は2つあると思います。
➀try-catch-finally 文が書けていない
➁データベースを開く場所が誤っている
もし、同じ状況で悩んでいる方の参考になればと思い記事にすることにしました。
##➀try-catch-finally 文が書けていない について
この後のコードを見るとわかるかと思いますが、私のコードは必要な try-catch が書けていません、、そもそも catch文を書いていないコードだったのでとても不安定なコードです。try-catch の重要性はわかるのですが、難しい。。まだまだ勉強が必要だと思いました。
複雑な try-catch を考えるより後述の「try-with-resources」を使ったほうがいいと思います。
##➁データベースを開く場所が誤っている について
###落ちるコード
コードの全文はこちら(私の書いた別記事に飛びます)
1回登録するだけなら落ちません。
2回登録しようとすると「java.lang.illegalStateException attempt to re-open an already-closed object」という例外が出ます。
なぜなら、落ちるコードはデータベースを onCreate メソッドで開いているからです。
onCreate メソッドはアプリを起動したら初めに実行されるメソッドです。私はここでデータベースを開き、いろいろ処理をしたのちデータベースを解放しています。それを再び操作しようとしても、 onCreate で閉じてしまったのでアプリが落ちてしまうというわけです。
public void insertData(SQLiteDatabase db, String maxBP, String minBP, String pulse){
ContentValues values = new ContentValues();
try {
values.put("_maxBP", maxBP);
values.put("_minBP", minBP);
values.put("_pulse", pulse);
db.insert("_BPtable", null, values);
} finally {
db.close();
}
}
##try-with-resources
try-with-resources の利点は複雑な try-catch 文を書かなくて良いというところだと思います。try-catch がわからない私には大助かり とはいえ try-catch-finally だけ実装されているプログラムのほうが多いと思うので勉強頑張ります。。
try-with-resources の構文はこちら
try (closeによる後片付けが必要な変数の宣言) {
本来の処理
} catch (例外クラス 変数名) {
例外が発生した場合の処理
}
先のコードを try-with-resources を用いて書き直したものがこちら
さらに、データベースをメソッドで開けるようにコードを見直しました。➁解決です。
public void insertData(String maxBP, String minBP, String pulse){
ContentValues values = new ContentValues();
DatabaseHelper helper = new DatabaseHelper(MainActivity.this);
try (SQLiteDatabase data = helper.getWritableDatabase()){
values.put("_maxBP", maxBP);
values.put("_minBP", minBP);
values.put("_pulse", pulse);
data.insert("_BPtable", null, values);
} catch (Exception e){
e.printStackTrace();
}
}
これで try が終わったあと自動的にデータベース解放処理が行われます.
連続登録落ちしないプログラムができました!
##参考
WINGSプロジェクト 齊藤新三 著/山田祥寛 監修『Androidアプリ開発の教科書』
中山清喬 著/国本大悟 著/株式会社フレアリンク 監修『スッキリわかるJava入門 第3版』