- AndroidアプリではSQLite3がデータベースとして利用できる
- 基本的なデータベースに対するCRUDのためのヘルパーメソッドはあるが、DDLはSQLリテラルを定義して投げる必要があるようだ
- O/Rマッパーは標準では装備していない
- /res/ディレクトリ以下にXML形式の設定を沢山並べると、R.javaクラスが自動的に更新される
- チュートリアルのアプリにはメモリが漏れるバグがあるので修正してみた
Android SDKのノートアプリケーションを作るチュートリアルをやってみたので、普通のJavaアプリと異なる点やAndroid開発で独自な点などを挙げてみます。
■データベースアクセス
AndroidのアプリではSQLite3がバックエンドデーターベースとして使用できるようです。データベース名とテーブル名を指定してデータベースを作成することが出来ます。
他のAndroidアプリが使用しているデータベース名と同じ名前をデータベース名として指定したときの挙動は未調査です。おそらくはセキュリティの観点上分けてあるはず(他のアプリのデータベースに勝手にアクセスできるのはいくら何でもまずい)・・・だとは思うのですが。
その他、
Content Providerという他のアプリと共有できるデータソースが用意されているようなのですが、こちらは後ほど。今はまだ未勉強。
データアクセスの方法はSQLiteOpenHelperクラスで
SQLiteDatabaseオブジェクトをopenして、このオブジェクトを使ってSQLiteにアクセスするようです。基本的なCRUDアクセスはすべてメソッドとして提供されています。
ただしDDL(Create TableとかDropとかAlterとかTruncate)はすべて手打ちのSQL文字列を投げて実行するみたいです・・・
Create Tableまで手打ちなのがちょっといただけない感じですね。O/Rマッパーは標準装備されていないのでしょうか?深く調査したわけではないですから何とも言えませんが、やはりリソース的にO/Rマッパーは重くてキツイ?
■XMLによるビューと文字列のリソース定義
ここが普通のJavaアプリと一番異なる点かな。/res/ディレクトリ以下でXMLを定義すると、R.javaというクラスファイルが自動的に生成されたり更新されたりします。
このR.java内の定数定義を用いてJavaソース上でXMLリソースを指定するというのが、Android(のActivity)開発でもっとも特異な点に思えます。たとえばこんな感じ。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.notepad_list); //ココ
mDbHelper = new NotesDbAdapter(this);
mDbHelper.open();
fillData();
}
不思議な感じですが一度慣れると病みつき。定数で定義出来るというのが便利。普通はsetContentView("R.layout.notepad_list")みたいに文字列で指定するのが一般的だと思いますが、これだとミスタイプしてもコンパイルエラーにならないし、何よりEclipseの入力補完が効かない。
で、XMLファイル自体の書き方もちょっと癖がある。たとえばandroid:id属性値の指定の仕方。
ListView id="@android:id/list"
TextView id="@android:id/empty"
このように@android:を使って指定すると、android.Rという最初からアンドロイドが用意してくれているクラスの設定を読み込むらしい。詳しくはEclipseでRという名前のclassファイルを読み込んでみると分かる。へぇーそーなのかー。
TextView id="@+id/text1"
このように指定すると、自分のアプリのRクラスから設定を読み込む。+をつけると設定がなければ自動的にRクラスを設定してくれる。
試してはいないが、おそらく+をつけないと自動的にRクラスを設定してくれないと思う。=見つからなくてエラー?になるのかな?
■チュートリアルにはバグがあります
無事チュートリアルで作ったアプリが動いたんですが、実はこのアプリにはバグがあります。
LogCatを開いたところ。ご覧のように、最後データベースをclose()していないためメモリが漏れてExceptionが発生しています。
(きちんとメモリ漏れを検知してExceptionを出してくれるdarvic VMは偉いと思う)
というわけできちんとデータベースをclose()してあげましょう。
Activityのライフサイクルは以下のようになっているので・・・
http://code.google.com/android/reference/android/app/Activity.html
Activity.onDestroy()をoverrideして、そこでデータベースをclose()すればよさそうですね。
@Override
public void onDestroy() {
mDbHelper.close();
super.onDestroy();
}
再度試したところエラーが消えました。ふう。