新たなAPI群に対して、それらを用いてアプリケーションを構築する方法を学ぶプロセスは、プラットフォーム自体がどれほど異なっていても、多くの場合よく似ています。これらは一般にAPIを用いて、どのようにやりたいことを実現するかを学ぶフェイズとプラットフォームの持つニュアンスを理解するフェイズという、2つのフェイズからなります。別の言い方をすると、『どうすれば実現出来るか』を学んだ上で、『どのように実現すべきか』を学ぶということになります。
ここに挙げた、アプリケーション構築の正しい道筋を学ぶという第二フェイズには時間がかかり、試行錯誤を重ねることになるでしょう。それではあまり効率がよくないので、このページとここにあるリンクにより、良い道筋を見つけ易いようにしています。
本論に入る前に、良いアプリケーションは良いユーザ体験を実現する、ということを頭に入れておいてください。Androidチームは堅牢なコアシステムを構築していますが、ユーザ体験のほとんどの部分はアプリケーションとのインタラクションにより生まれることになります。そのため、我々はアプリケーション開発者が良いユーザ体験を生み出すのに時間を費やすべきだと考えています[※1] 。
良いユーザ体験は、『高速動作』、『高速応答』、『シームレス』という3つのファクタから成っています。この3つを同時に満たすための方法はプラットフォームごとに異なり、往々にして大変なことでありますが、Androidには以下で解説するような手法を取ります。
Androidアプリケーションは高速動作すべきです。より正確には、効率よく動作すべきというべきでしょう。コンピュータ業界おいては、最終的にはムーアの法則により全ての問題が解決するという風潮が見られますが、組み込みアプリケーションにおいてはPC向けとは異なった事情があります。
モバイルデバイスにおいて、ムーアの法則はデスクトップやサーバ向けアプリケーションと同じようには当てはまりません。ムーアの法則とはあくまでも、時間の経過により同じサイズのチップの中にどれほどのトランジスタを集積出来るようになるかという話です。デスクトップアプリケーションにおいては、これが『大体同じ大きさのチップでより高速処理出来るようになる』という意味になりますが、携帯電話などの組み込みアプリケーションにおいてムーアの法則は、『チップをどれほど小さく出来るか』という向きに働きます。つまり、いかにチップを小さくし消費電力を削減し、バッテリ駆動時間を長持ちさせるかという向きに働くのです。結果的に、携帯のような組み込みデバイスにおいて処理速度は徐々に向上していくものの、バッテリ駆動時間が最優先で性能は二の次なので、デスクトップ向けよりもゆるやかなスピードでの向上となるのです。
繰り返しになりますが、携帯の処理高速化はPCよりも緩やかであるため、効率的なアプリケーションを書く必要があります。一般にはメモリ消費量が少なく、きちんと動作し、パフォーマンス低下を招く言語やプログラミングのイディオムを使わないことが重要とされます。オブジェクト指向においては、大体の場合メソッドレベルの話で、コードの行数、ループといった要素に関連します。
Androidにおいて高速で効率の良いコードを書くための方法はWriting Efficient Android Codeにありますので参照下さい。
どんなパフォーマンステストでも再考の評価を得られるのに、実際に使ってみるとユーザを怒り狂わせてしまうようなコード、というものが考えられます。つまり、もたついたり、ハングアップしたり、長い間フリーズしてしまったり、入力処理にあまりにも長い時間がかかったりと、応答性が良くないものです。Androidにおいては、応答性が悪いアプリケーションに対してはシステムがしょっちゅう『アプリケーションが応答しません』(Application Not Responding; ANR)というメッセージを表示することになるでしょう。
一般に、ユーザからの入力に応答できないケースというのは発生します。例えばネットワークアクセスなどのI/O待ちによりブロックされている場合などは、アプリケーションのメインスレッドがユーザからの入力イベントを処理出来ない状態となります。時間が経つと、システム側でアプリケーションがハングアップしたとみなし、ユーザにプロセスを終了するオプションを提示します。同様に、メモリ上のデータ処理を長時間行ったり、ゲームの次の動きを長考したりしている際にもシステムはアプリケーションがハングアップしたとみなします。これらの計算を前述のテクニックにより効率化するのはもちろんですが、そうしてもなお実行に時間のかかる場合もあります。
いずれの場合にしても、一般的な解決策は子スレッドを作成してそこでほとんどの処理を行うことです。これによりユーザインターフェイスのイベントを受け取るメインスレッドが応答可能な状態を保ち、またシステム側でアプリケーションがフリーズしたとみなすことも回避出来ます。つまりここでの応答性とは、前述した『メソッドレベル』の議論とは別物で、『クラスレベル』の問題であること考えることが出来ます。
高速応答に関する議論の詳細は、Building Responsive Android Applicationsをご覧下さい
例えアプリケーションが効率よく、応答性よく動作したとしても、まだ十分とは言えません。分かり易い例はServiceやIntentReceiverといったイベントへの応答にUIへのポップアップを行うバックグラウンドプロセスです。これはアプリケーション自体のテストを重点的に行われることが多い開発側においてあまり気にかけられません。しかしAndroidのアプリケーションモデルは、ユーザがアプリケーション間を滑らかに切り替えられるように構成されており、バックグランドプロセスがUI表示を行った時に、ユーザが電話をかけるなど他の作業をしている最中かもしれません。SMSサービスが、メッセージ着信のたびにダイアログボックスを表示すると、ユーザ側としては鬱陶しいものだと思いませんか?そのため、ユーザを邪魔せずに情報通知を行う機構として、Androidでは通知アイコンの利用を標準としています。
これは単なる一例にすぎず、他にも様々なケースが考えられます。例えば、アクティビティがonPause()などのライフサイクル管理用メソッドを正しく実装しなかった場合、データ喪失がしょっちゅう発生することになるでしょう。あるいはアプリケーションからデータを他のアプリケーションに公開したい場合は、通常のファイルやデータベースではなくContent Providerを利用すべきです。
つまりは、システムや他のアプリケーションとうまくやっていけるような形でアプリケーションを構築することが重要ということです。Androidシステムはアプリケーションを単一の大きなブラックボックスというよりは、疎結合のコンポーネント群として扱います。これにより開発者からシステムは、更に大きなコンポーネント群と見ることが出来ます。このため、データを公開出来る形としておくことですっきりとかつシームレスに他のアプリケーションとの統合を図ることが出来ます。[※2]
これは前述の『クラスレベル』、『メソッドレベル』の概念とはまた異なる『コンポーネントレベル』の概念です。Integrating with the Systemの記事に、システムのほかの部分と協調動作するコードを書くコツが書かれていますので参考にして下さい。