2012/06/27

CursorLoaderとAsyncTaskLaoderを使ったアプリのソースコードを公開してみた

最初は「Android 3.0以前でのFragmentとLoaderによるプログラミングのすゝめ」というタイトルにしたのですが、説明的すぎたので止めました。

さて、本屋さんでは、あんざい ゆきさんの本などを除いて、初心者向けのAndroid本のほとんどで、FragmentやLoaderについての記述がある本をみることはありません。

初心者向け本が備えるべき要件をここで書くつもりはないので、何が初心者向けなのかは議論の余地があると思いますが、網羅的な本を読むよりは、多少偏ってもアプリケーションを一つ作って、その周辺知識を増やしていく方が学習方法としては効果的じゃないかなと考えています。

その点では良い土台が必要なんじゃないかなと思うわけですが、そのうちAndroid 2.3を対象にしたアプリケーションでもFragmentやLoaderを使ったプログラミングを推奨する「やり直し本」が出てくるんじゃないかなと期待しているんですが、どうするべきなんでしょうね。

Android 1.6の頃はThreadを生成して、Handlerオブジェクトに処理を実行させるコードを書いた事もあったかもしれませんが、アプリケーションを見通し良く開発していくためには、新しい方法を取り入れて進んでいくしかないと思っています。

互換ライブラリを使ったアプリケーションの開発

CursorLoaderはContentProviderに対するwrapperのように使えば良いのですが、そういう説明をみなかったので実際にアプリケーションを作ってみました。

アプリケーションのベースは以前作成した「日本の郵便番号検索 Free」で、郵便番号の3桁+4桁の数字のみを入力するようにして、内部のコードはシンプルに保っています。

作成したアプリケーションのスクリーンショット

内部構造や使う仕組みは一部は流用していますが、ほぼ新規に作成しています。 ログの出力用メソッドに対する工夫など、役に立ちそうな部分は極力反映したつもりです。

このアプリケーション「Yamaneko」のソースコードはApache License 2.0でGithubにて公開してます。

アプリケーションの導入や内部構造について

使うためのEclipseの操作方法はスクリーンショットを交えて説明しているので、内部構造の説明を含めてgithubのwikiを参照して下さい。

データフロー概要

実際にアプリケーションを作って感じたこと

「動けばいい」というのではなくて、内部構造をシンプルに保ちつつ見通しのよいコードを書くために、普通はフレームワークを開発します。

Android 3.0やCompatibility Packageで提供されている新しいクラスは、そういう新しい(抽象度は低めかもしれませんが)フレームワークに相当する処理で、開発元が公式に提供しているものとなります。

その点では独自になにか仕組みを作るよりは、馴染むまでに時間がかかるかもしれませんが、できるだけ使った方が良いスタイルを強制できる事になります。

初心者向けの雛型アプリケーション

GNU公式のGNU Helloアプリのソースコードを雛型に開発をしようとして、その完成度の高さのあまりに挫折した人も多いのではないでしょうか。

まぁ、GNU Helloはほとんどネタですけれど、Androidでも似たようなアプリケーションが必要なのかもしれません。

本屋さんでAndroidの初心者向け開発本を眺めた印象では、初心者向けの良い雛型アプリケーションを提供する本がないなぁという印象を受けました。

内部構造を知るためにAndroidのframeworks/base/coreディレクトリにあるソースコードを見るのは普通だと思いますが、アプリケーションを開発するための土台としては、何か参考になるか聞かれて「GNU Helloみてみたら」みたいな定番があった方が便利じゃないでしょうか。

ApiDemoアプリも良いんですけれど、単品の機能だけなので、連携が分からないところがネックかなと思っています。

非同期処理のための他の方法との比較

メインUIやContentProvider, Serviceプロセスをブロックしないためには、HandlerやAsyncTaskクラスを使えば、AsyncTaskLoaderを使う必要は必ずしもありません。

仕組なくともProgressViewでアップデートするためにはAsyncTaskLoaderは適切ではなくて、AsyncTaskクラスの方が便利でしょう。

今回、CusrorLoaderとAsyncTaskLoaderを使った印象は、自前でAsyncTaskを管理してContentProviderの内部からタスクを起動するよりも、AsyncTaskLoaderでネットワークアクセスのみを扱い、ListViewへの出力はCursorLoaderと平行に起動できるのは内部構造としては見通しが良く、管理もしやすかったです。

外部のWebサービスから結果を取得して表示するアプリケーションでは、今回の構造がいまのところベストかなと思います。

表示するデータをContentProviderに管理させる構成について

直感的には自分のアプリケーションで表示するデータをDBに入れるだけではなくて、そのためにContentProviderのサブクラスを作成して、AndroidManifest.xmlに登録するというのは冗長に感じます。

とはいえ、twitterのタイムラインのように、ListViewやGridViewに表示する項目数が想定できないような場面では、データベースを中継してCursorオブジェクトでListViewやGridViewに表示する方法がベストです。

多少面倒でも、SimpleCursorAdapterとCursorLoaderを組み合せるのは良い方法だと思います。 パフォーマンスが懸念される場面でListAdapterを使うというのは、いまのところ納得していません。

また、副次効果としてSQLiteDatabaseオブジェクトをContentProviderクラスだけが扱うことになるのは良い構造だと思います。

さいごに

自分のコードが最善だとは到底思えないので、アプリケーションのコードを公開するのは気が重いです。

Androidアプリのソースコードは、あまりみないので、公開しようかなと思ったのですが、 Apache License 2.0やGPLv3などのライセンス別にまとめるサイトがあってもいいかもしれません。

いろいろ叩かれるとしても、それを乗り越えられるなら、コードを隠しても良い事はほとんどないですからね。

次に勤める会社があるなら、その会社との契約に縛られない限りは、 まとまった処理単位での動きが確認できるアプリケーションのコードはこれからも公開していきます。

0 件のコメント: