2008年10月13日月曜日

Android チュートリアル: Notepad Exercise 1

  • 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();
}
再度試したところエラーが消えました。ふう。

2008年10月12日日曜日

一通りレイアウト調整完了

  • ストレッチデザインになって横に長い日でも安心、IE7でも綺麗
  • タグクラウドはNew Blogger Tag Cloud / Label Cloud様からお借りしました
  • フォントが気に入らないのでそこは直すかも
  • 上に表示されるBloggerバーがいまいち
無事レイアウト調整が終わりましたので、今後はこちらをメインに使っていこうかと思います。
preタグをいちいち自分で入れなくてはいけないのが相変わらずですが、デザインがシンプルで横に長く、ソースコードを沢山入れることが出来そうです。行間がきちんと取られているのも読みやすくて素敵ですね。

欠点として、画像がPicasaサーバーに置かれるようになったのがちょっと迷惑です。あと上に表示されるバーを消したいです(ちょっと邪魔・・・)。

エディタはなかなか使いやすいです。下書きの自動保存が何より一番嬉しい。

テスト投稿

  • Bloggerの機能を試してみる
  • ソースコードはどれぐらい入れられるのか
  • クロスブラウザ対応は?
普通のテキスト 太字 斜体 文字色

左揃え
中央
右揃え
両端揃え・・・はうまくいかないな
  1. 番号リスト
  2. リスト
  3. リスト
引用
これがうまくいくとすごく助かる
if __name__ == '__main__':
sys.path = EXTRA_PATHS + sys.path
script_name = os.path.basename(__file__)
script_name = SCRIPT_EXCEPTIONS.get(script_name, script_name)
script_path = os.path.join(SCRIPT_DIR, script_name)
execfile(script_path, globals())

画像を追加してみたい


ちょっと大きいかな
引用はうまくいかないのでpreタグを試してみる
if __name__ == '__main__':
sys.path = EXTRA_PATHS + sys.path
script_name = os.path.basename(__file__)
script_name = SCRIPT_EXCEPTIONS.get(script_name, script_name)
script_path = os.path.join(SCRIPT_DIR, script_name)
execfile(script_path, globals())