Androidことはじめ

この記事を読むのに必要な時間の目安: 19分ぐらい



Androidとは・・・GoogleとOpen Handset Allianceによって作られた携帯電話のためのOSS Tool Kit。
・ロイヤリティを支払うことなく、プラットフォームを利用したりカスタマイズできる。
・1つのベンダーに縛られていない。(Windows PhoneであればMicrosoft。iPhoneであればApple。)
・すべてJavaで書かれ、Dalvik仮想マシンによって実行されるためARM,x86,その他のアーキテクチャにまたがって移植性が確保されている。


構図



<Linuxカーネル>
Androidは安定した環境として定評のあるLinuxカーネルのもとで動作するように作られている。
Linuxはヘルシンキ大学の学生だったLinus Torvaldsが1991年に開発したOS。
LinuxがAndroidに対してハードウェア抽象化レイヤを提供しているので
将来のAndroidは様々なプラットフォームに移植できるはず。


Androidは

 ・メモリ管理
 ・プロセス管理
 ・ネットワーキング
 ・その他のシステムサービス

の実行のためにLinuxを使っている。
AndroidケータイのユーザからはLinuxは見えないし、プログラムも直接的なLinux呼び出しは行わない。

しかし、デベロッパとしてはLinuxがあることを意識する必要がある。
たとえば、adb shellコマンドを実行するときとか。
adb shellコマンドを叩くと、Linuxシェルがオープンされる。
シェルからはセキュリティ上の制約の範囲内でLinuxファイルシステムを見たり、
アクティブなプロセスを見たりすることができる。
#ま、rootを取ってしまえば、セキュリティ上の制約もクソもそんなの関係ねぇ!ってな状態だけど。

<ネーティブライブラリ>
カーネルのすぐ上のレイヤはAndroidネーティブライブラリ。
こいつはC or C++で書かれた共有ライブラリでケータイが使っているハードウェアアーキテクチャに特化した形で
コンパイルされていおり、ケータイメーカーによってプレインストールされている。

ネーティブアプリで特に重要なものは次のもの。

●サーフェスマネージャ
 AndroidはVistaやCompizとよくにているが、ずっと単純な複合ウィンドウマネージャを使っている。
 描画コマンドは画面バッファに直接書き込まれるのではなく、オフスクリーンビットマップに送られ、
 そこでほかのビットマップと結合されてユーザが見る画面になる。
 こうすることによりシステムはシースルーウィンドウとか
 画面のおしゃれな切り替えといった面白い効果を生み出すことができる。

●2D、3Dグラフィック
 Androidに対する単一のユーザインタフェースに2D/3Dの要素を結合できる。
 このライブラリはデバイスが3Dハードウェアを持っていればそれを使い、
 そうでなければ高速ソフトウェアレンダラを使う。

●メディアコーデック
 AndroidはAAC、AVC(H.264)、H.263、MP3、MPEG-4などの様々なフォーマットを持つビデオの再生と
 オーディオの録音/再生をサポートしている。

●SQLデータベース
 AndroidにはFireFoxやiPhoneが使っているのと同じSQLiteデータベースエンジンが搭載されている。
 このデータベースはアプリケーションの永続記憶として使える。

●ブラウザエンジン
 AndroidはHTMLコンテンツの高速表示のためにWebKitライブラリを使っている。これはGoogle Chromeブラウザ、
 AppleのSafariブラウザ、iPhone、Nokia S60プラットフォームが使っているのと同じエンジンである。

これらのライブラリは自立したアプリケーションではない。より高い水準のプログラムから呼び出されるだけである。
Android1.5以降、NDK(Native Development Kit)を使って独自のネーティブライブラリを書いてデプロイできるようになった。

<Androidランタイム>
カーネルの上にはAndroidランタイムも乗っている。ランタイムにはDalvik仮想マシンとコアJavaライブラリが含まれている。
Dalvik仮想マシンはGoogleが実装したJavaで、モバイルデバイスに合わせて最適化されている。
Android用のコードはすべてJavaでかかれているので、このVMの中で実行される。
Dalvikは次の2つの点で従来のJavaとは大きく異なる。

●Dalvik VMはコンパイル時に標準の.class、.jarファイルから変換、生成された.dexファイルを実行する。
 .dexファイルは.classファイルよりも小さく効率的であり、
 Androidのターゲットであるバッテリ駆動でメモリの小さいデバイスに適している。

●Androidに付属しているコアJavaライブラリはJava SE(Java Standard Edition)ライブラリや
 Java ME(Java Mobile Edition)ライブラリとは異なるが、重なり合う部分は多い。

「Dalvik」とは何か
 DalvikはGoogleのDan Bornsteinによって設計、実装された仮想マシン(VM)である。
 自分で書いたコードはマシンに依存しないバイトコードと呼ばれる命令にコンパイルされ、
 それがモバイルデバイスに搭載されているDalvik仮想マシンによって実行される。
 
 バイトコードの形式にわずかな違いはあるが、Dalvikは基本的にメモリが少ない環境に合わせて
 最適化されたJava仮想マシンである。同時に複数のVMインスタンスを実行でき、
 セキュリティやプロセスの隔離については下のOS(Linux)を利用できる。

 Dalvikという名前はBornsteinの祖先が住んでいたアイスランドの漁村にちなんで付けられたものである。

<アプリケーションフレームワーク>
ネーティブライブラリとランタイムの上にはアプリケーションフレームワークのレイヤがある。
このレイヤはアプリケーション開発のために使える高水準の部品を提供する。
このフレームワークはAndroidにプレインストールされた形で提供されるが、
必要に応じて独自コンポーネントを追加して拡張することができる。

フレームワークの中で重要な部分は次のものである。

平等と拡張
Androidのユニークで協力な特徴の1つはすべてのアプリケーションが平等な立場にいることである。
システムアプリケーションと言っても自分が使うのと同じ公開APIを使わなければならない。
必要なら標準アプリケーションの代わりに自作のアプリケーションを使うようAndroidに指示することさえできる。

●アクティビティマネジャ
 アプリケーションのライフサイクルを支配しユーザナビゲーションの共通「バックスタック」を管理する。

●コンテンツプロバイダ
 アドレス帳などのようにアプリケーションの間で共有しなければならないデータをカプセル化する。

●リソースマネージャ
 リソースとはプログラムに含まれるコード以外の部分ことである。

●位置マネージャ
 Androidケータイはいつでも自分の場所を把握している。

●通知マネージャ
 メッセージの到着、約束の時間、近接アラーム、外部からの侵入などのイベントは
 邪魔にならない形でユーザに知らされる。

<アプリケーションとウィジェット>
Androidのアーキテクチャ図で最も上のレイヤに配置されるのはアプリケーションとウィジェットレイヤである。
アプリケーションはAndroidという氷山の頂点と考えることができるだろう。エンドユーザからはアプリケーションと
ウィジェットしか見えず、彼らは水面下で行われるあらゆる動きを知らずにいることができる。
しかし、Androidデベロッパは、もっと多くのことを知らなければならない。

・アプリケーションは画面全体を占有してユーザとやり取りをするプログラムである。
 それに対し、
・ウィジェット(ガジェットと呼ばれることもある)はHome画面の一部の小さな矩形の中だけで動作する。

Android搭載機を買ってくると次に示すような標準システムアプリケーションがあらかじめインストールされている。

●ダイアラ
●電子メール
●アドレス帳
●Webブラウザ
●Android Market

<生きているアプリケーション>
LinuxやWindowsの標準的なデスクトップでは多くのアプリケーションを様々なウィンドウに同時に表示させることができる。
それらのウィンドウのうち1つだけがキーボードフォーカスを持つが、それを除けば、すべてのプログラムは平等である。
プログラムの切り替えは簡単であり、自分の操作が見えるようにウィンドウを動かしたり、不要になったウィンドウを
クローズしたりするのはユーザの仕事である。

でも、Androidはそのようには動いていない。
Androidにはフォアグラウンドアプリケーションが1つあり、一般的にはそれがステータス行以外の画面全体を占有している。
ユーザがケータイの電源を入れると最初に表示されるのはHomeアプリケーションである。
このアプリケーションは一般に時刻、背景イメージ、ユーザが実行できる他のアプリケーションの
スクロールできるリストを表示する。

ユーザがアプリを実行するとAndroidはそれを起動してフォアグラウンドに配置する。
ユーザはそのアプリからさらに別のアプリを起動したり、同じアプリの別の画面を表示したり、
別のアプリの今までとは別の画面を表示したりできる。
これらのプログラムや画面はシステムのアクティビティマネージャによってアプリケーションスタックに記録される。
ユーザはBackボタンを押せば、スタックに含まれている前の画面にいつでも戻ることができる。
ユーザから見るとWebブラウザのヒストリ(履歴)機能のように感じられるだろう。
Backを押すと、前のページに戻るのだ。

<プロセス!=アプリケーション>
個々のユーザインタフェース画面はActivityクラスによって表現される。
個々のアクティビティはそれぞれ自分のライフサイクルを持っている。
アプリは1つ以上のアクティビティとそれを格納するLinuxプロセスである。

Androidではアプリケーションはプロセスが殺された後でも「生きている」ことができる。
言い換えればアクティビティのライフサイクルとプロセスのライフサイクルにはずれがある。
プロセスはアクティビティを入れる使い捨ての容器に過ぎない。
これは他のどのようなシステムともおそらく異なる形である。


Androidプログラムの個々のアクティビティはいくつかの状態の中のどれかに属している。
デベロッパはプログラムの状態を自分で変えることはできない。状態は100%システムによって管理されている。
しかし、状態が変わろうとする直前にonXX( )メソッド呼び出しを通じて通知が送られてくる。

Activityクラスでこれらのメソッドをオーバーライドすれば、Androidは適切なタイミングでそれらを呼び出す。

●onCreate(Bundle)
 アクティビティが最初に起動するときに呼び出される。これを利用すればUIの作成など、
 一度だけ実行される初期化処理を実行できる。onCreate( )には引数が1個渡される。
 その値はnullかonSaveInstanceState( )メソッドで保存された何らかの状態情報である。

●onStart( )
 アクティビティが表示される直前だということを知らせる。

●onResume( )
 アクティビティがユーザとのやり取りを始められるようになる直前に呼び出される。
 アニメーションや音楽を開始するタイミングとして適切である。

●onPause( )
 アクティビティがバックグラウンドに隠れる直前に呼び出される。
 通常、隠れる原因は他のアクティビティが起動されて、現在のアクティビティよりも手前に出てくることにある。
 編集中だったデータベースレコードなどは、このタイミングで永続記憶に保存するとよい。

●onStop( )
 アクティビティがユーザからは見えなくなり、しばらく不要になった時に呼び出される。
 メモリの残量が少なくなるとonStop( )は呼び出されない場合がある。(システムが単純にプロセスを破棄してしまう場合)

※状態保存コードが正しく動作しているかどうかを簡単にテストできる方法。
 デバイスの向きが変わると(横長モードと縦長モードの間の切り替え)、システムがインスタンス状態の保存、
 一時停止、終了、破棄を行い、保存された状態を使ってアクティビティの新しいインスタンスを作る。

●onRestart( )
 終了状態だったアクティビティが再び表示されようとしていることを知らせる。

●onDestroy( )
 アクティビティが破棄される直前に呼び出される。メモリの残量が少なくなると、
 onDestroy( )が呼び出されない場合がある(システムが単純にプロセスを破棄してしまう場合)。

●onSaveInstanceState(Bundle)
 Androidはテキストフィールド内のカーソル位置などのインスタンスごとの状態情報を
 アクティビティに保存させるためにこのメソッドを呼び出す。
 しかし、デフォルト実装が自動的にUIコントロールのすべての状態を保存してくれるので、
 通常、これをオーバーライドする必要はない。

●onRestoreInstanceState(Bundle)
 前にonSaveInstanceState( )メソッドで保存された状態からアクティビティが再初期化される直前に呼び出される。
 デフォルト実装はUIの状態を復元する。

フォアグラウンドで実行されていないアクティビティは新しいアクティビティのためのスペースを作るために、
いつでも終了される可能性がある。終了とはコンテナのLinuxプロセスを終了させることである。
これはよく起きることなので最初からこれを計算に入れてアプリケーションを設計することが大切。
アクティビティの中で最後に呼び出されるメソッドがonPause( )になる場合があるので、
次回実行時のために残しておきたいデータは、このタイミングで保存していなければならない。

Androidのフレームワークはプログラムのライフサイクルを管理するだけでなく、
アプリケーション開発のために使える部品も提供している。

<開発のための部品>
 Android SDKには、すべてのデベロッパがよく知っていなければならないオブジェクトが定義されている。
 その中でも最も重要なのはアクティビティ、インテント、サービス、コンテンツプロバイダである。

●アクティビティ
 UI画面のこと。アプリはプログラムの異なる側面を処理するために1つ以上のアクティビティを定義できる。
 個々のアクティビティはアプリのライフサイクルの一部として後で復元できるようにするために、
 自らの状態を保存しなければならない。ActivityクラスはContextを継承しているので、
 これを使えばアプリのグローバル情報が手に入る。

●インテント
 「写真を選択する」、「家に電話する」、「ポッドの開閉口を開けろ」などのアクションを記述するメカニズムである。
 Androidではほとんどすべてのものがインテントを経由するのでコンポーネントを交換、再利用するチャンスは無数にある。
 たとえば「電子メールを送る」というインテントがある。メールを送らなければならなくなったアプリケーションは
 そのインテントを呼び出せば良い。新しい電子メールアプリを書いている場合にはインテントを処理するアクティビティ
 として自作のものを登録し、標準のメールアプリの代わりに使うことができる。次に誰かが電子メールを送ろうとしたときには、
 標準のメーラではなく、自分で作ったアプリが起動される。

●サービス
 Unixデーモンと同じようにユーザとの直接的なやり取りを行わず、バックグラウンドで実行されるタスクである。
 たとえば、ミュージックプレイヤについて考えてみよう。音楽はアクティビティによって開始されるかもしれないが
 ユーザが別のプログラムに移動しても、音楽の再生は続けたいところだ。そこで、実際に再生を行うコードは
 サービスにするのである。後でほかのアクティビティがサービスにバインドされれば、トラックの変更や再生の停止を
 命令することができる。Androidには多くのサービスが組み込まれており、それらにアクセスするための便利なAPIも
 用意されている。ライブウォールペーパーはサービスを使ってHome画面の背景として動画を描画している。

●コンテンツプロバイダ
 コンテンツプロバイダは読み書きするためのカスタムAPIを持つデータの塊である。
 アプリケーションの間でグローバルデータを共有するための最良の方法となっている。
 たとえば、Googleはアドレス帳のためのコンテンツプロバイダを提供している。アドレス帳に含まれている名前、
 住所、電話番号などの情報はそれを必要とするすべてのアプリケーションの間で共有できる。

<リソースの使い方>
リソースとはローカライズされた文字列、ビットマップ、その他プログラムが必要とする小さなコード以外の情報のこと。
リソースはビルド時にアプリに組み込まれる。リソースは国際化や複数のデバイスタイプのサポートで役に立つ。

リソースはプロジェクトのresディレクトリに作成する。Androidのリソースコンパイラ(aapt)はリソースが格納されている
サブフォルダとファイルフォーマットを手がかりにしてリソースを処理する。たとえば、PNG、JPGフォーマットの
ビットマップはres/drawableディレクトリに格納し、画面レイアウトを記述するXMLファイルはres/layoutディレクトリに
格納しなければならない。また、特定の言語、画面の向き、解像度などを表すサフィックスを追加することもできる。

リソースコンパイラはリソースを圧縮、パッキングして、プログラム内でリソースを参照するために使う識別子を格納した
Rという名前のクラスを生成する。これはキー文字列で参照されるJavaの標準リソースとは異なる。
このような方法をとることによって、Androidは無効な参照を作らないようにするとともにリソースキーを不要にして
スペースを節約しているのである。Eclipseは同様の方法を使ってEclipseプラグインのリソースを格納、参照している。

<アクセス保護とセキュリティ>
アプリケーションは自分用のLinuxプロセスの中で実行される。ハードウェアはプロセスがほかのプロセスのメモリにアクセス
することを禁止する。さらにアプリケーションには特定のユーザIDが対応付けられる。
アプリケーションが作成したファイルは他のアプリケーションからは読み書きできない。

さらに特定のクリティカルな処理へのアクセスは制限され、AndroidManifest.xmlというファイルを使って特に許可を
求めなければならない。アプリケーションがインストールされるときにパッケージマネージャが証明書に基づいて
(必要な場合はさらにユーザに問い合わせて)許可するかどうかを決める。
許可が必要な処理の中でもっとも一般的なものをまとめると・・・

●INTERNET
 インターネットにアクセスする。

●READ_CONTACTS
 ユーザのアドレス帳データを読み出す(書き込みはしない)

●WRITE_CONTACTS
 ユーザのアドレス帳データに書き込む(読み出しはしない)

●RECEIVE_SMS
 受信されるSMS(ショートメッセージ)をモニタリングする

●ACCESS_COARSE_LOCATION
 携帯中継局やWiFiなどの制度の低い位置プロバイダを使う

●ACCESS_FINE_LOCATION
 GPSなどのより正確な位置プロバイダを使う

たとえば、送られてくるSMSメッセージをモニタリングするためにはマニフェストファイルに次のような指定が必要となる。

Androidはシステム全体へのアクセスを制限することさえできる。AndroidManifest.xmlのXMLタグを使えば
アクティビティの起動、サービスの開始、バインド、レシーバへのインテントのブロードキャスト、
コンテンツプロバイ内へのアクセスなどを制限できる。この種の制限についてはAndroidセキュリティモデルの
オンラインヘルプ
を参照。

は~疲れた!
ここまで、何とか頭に叩き込みました!