110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertypage.title=開発の基礎 210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty@jd:body 310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<div id="qv-wrapper"> 510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<div id="qv"> 610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h2>主なクラス</h2> 710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ol> 810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>{@link android.app.Activity}</li> 910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>{@link android.app.Service}</li> 1010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>{@link android.content.BroadcastReceiver}</li> 1110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>{@link android.content.ContentProvider}</li> 1210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>{@link android.content.Intent}</li> 1310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ol> 1410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 1510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h2>このドキュメントの内容</h2> 1610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ol> 1710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><a href="#appcomp">アプリケーションのコンポーネント</a> 1810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <ol> 1910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#actcomp">コンポーネントのアクティブ化: インテント</a></li> 2010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#endcomp">コンポーネントの終了</a></li> 2110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#manfile">マニフェスト ファイル</a></li> 2210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#ifilters">インテント フィルタ</a></li> 2310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty </ol></li> 2410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><a href="#acttask">アクティビティとタスク</a> 2510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <ol> 2610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#afftask">親和性と新しいタスク</a></li> 2710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#lmodes">起動モード</a></li> 2810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#clearstack">スタックのクリア</a></li> 2910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#starttask">タスクの開始</a></li> 3010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty </ol></li> 3110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><a href="#procthread">プロセスとスレッド</a> 3210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <ol> 3310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#procs">プロセス</a></li> 3410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#threads">スレッド</a></li> 3510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#rpc">リモート プロシージャ コール</a></li> 3610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#tsafe">スレッドセーフなメソッド</a></li> 3710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty </ol></li> 3810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><a href="#lcycles">コンポーネントのライフサイクル</a> 3910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <ol> 4010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#actlife">アクティビティのライフサイクル</a></li> 4110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#servlife">サービスのライフサイクル</a></li> 4210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#broadlife">ブロードキャスト レシーバのライフサイクル</a></li> 4310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <li><a href="#proclife">プロセスとライフサイクル</a></li> 4410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty </ol></li> 4510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ol> 4610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</div> 4710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</div> 4810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 4910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 5010550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyAndroid アプリケーションはすべて Java プログラミング言語で記述します。コンパイル済みの Java コード(およびそのアプリケーションに必要なすべてのデータやリソース ファイル)は、<a href="{@docRoot}tools/aapt.html"><code>aapt</code> ツール</a>を使用して Android パッケージにバンドルします。Android パッケージは、拡張子が {@code .apk} のアーカイブ ファイルです。<i></i>ユーザーは、このファイルをデバイスにダウンロードして利用します。つまり、Android パッケージは、アプリケーションをモバイル デバイスに配布およびインストールするための媒体として機能します。1 つの {@code .apk} ファイルに含まれているすべてのコードが、1 つのアプリケーションと見なされます。<i></i> 5110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 5210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 5310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 5410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty各 Android アプリケーションは、以下に示すさまざまな方法で他のアプリケーションから隔離されています: 5510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 5610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 5710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 5810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>すべてのアプリケーションは、デフォルトではそのアプリケーション個別の Linux プロセスで実行されます。Android は、アプリケーション コードの実行が必要になったときにプロセスを開始し、その必要がなくなって他のアプリケーションからシステム リソースを要求されたときにプロセスを終了します。</li> 5910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 6010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>プロセスごとに専用の Java 仮想マシン(VM)が割り当てられるため、アプリケーション コードは他のアプリケーションから隔離された状態で実行されます。</li> 6110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 6210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>デフォルトでは、アプリケーションごとに固有の Linux ユーザー ID が割り当てられます。権限が設定されているため、アプリケーションのファイルはそのユーザーからしか認識できず、そのアプリケーション自体からのみ利用できます。ただし、ファイルを他のアプリケーションにエクスポートすることは可能です。</li> 6310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 6410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 6510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 6610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty2 つのアプリケーションで同じユーザー ID を共有することもできます。その場合は、それぞれのアプリケーションのファイルを相互に認識できます。システム リソースを節約するため、同じ ID のアプリケーションで同じ VM を共有し、同じ Linux プロセスで実行することも可能です。 6710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 6810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 6910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 7010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h2 id="appcomp">アプリケーションのコンポーネント</h2> 7110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 7210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 7310550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyAndroid の大きな特長の 1 つは、許可されていれば、あるアプリケーションから別のアプリケーションの要素を利用できる点です。たとえば、開発中のアプリケーションで画像の一覧をスクロール表示したい場合、他のアプリケーションで開発済みの適切なスクローラがあり、その利用が許可されていれば、独自に開発しなくてもそのスクローラを利用できます。アプリケーションに他のアプリケーションのコードを組み込んだり、リンクを設定したりする必要はありません。必要になった時点で、他のアプリケーションの一部分を開始するだけです。 7410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 7510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 7610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 7710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこの仕組みが機能するには、アプリケーション プロセスの一部分を必要に応じて開始でき、その部分の Java オブジェクトをインスタンス化できなくてはなりません。そのため、Android アプリケーションには、他のシステムで動作するアプリケーションでよく使用されるような、アプリケーション全体にアクセスするための単一のエントリ ポイント(たとえば {@code main()} 関数)はありません。代わりに、システムが必要に応じてインスタンス化して実行できるコンポーネントで構成されます。<i></i>コンポーネントには以下の 4 つのタイプがあります: 7810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 7910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 8010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dl> 8110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 8210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dt><b>アクティビティ</b></dt> 8310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dd>アクティビティは、ユーザーが 1 つの操作を集中的に行うための視覚的なユーザー インターフェースを表します。<i></i>たとえば、ユーザーが選択できるメニュー アイテムの一覧を表示するアクティビティや、写真をキャプション付きで表示するアクティビティなどが考えられます。SMS アプリケーションなら、あるアクティビティでメッセージを送信する連絡先の一覧を表示し、別のアクティビティで選択した連絡先へのメッセージを入力し、その他のアクティビティで古いメッセージを参照したり設定を変更したりできます。これらのアクティビティを組み合わせて全体としてのユーザー インターフェースを形成しますが、それぞれのアクティビティは相互に独立しています。各アクティビティは、{@link android.app.Activity} 基本クラスのサブクラスとして実装されます。 8410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 8510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 8610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアプリケーションは、1 つのアクティビティで構成することも、上記のSMS アプリケーションのように複数のアクティビティで構成することもできます。どのようなアクティビティがいくつ必要になるかは、アプリケーションやその設計に応じて異なります。通常は、アクティビティのうちのいずれかを最初のアクティビティとして指定し、ユーザーがアプリケーションを起動したときに表示します。あるアクティビティから別のアクティビティに移動するには、現在のアクティビティから次のアクティビティを開始します。 8710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 8810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 8910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 9010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty各アクティビティには、それを表示するためのデフォルトのウィンドウが割り当てられます。通常はウィンドウを画面全体に表示しますが、画面より小さいウィンドウを他のウィンドウの前面に表示することもできます。アクティビティに、新たなウィンドウを追加することも可能です。たとえば、アクティビティの途中でユーザーの応答を要求するポップアップ ダイアログを表示したり、ユーザーが画面上の特定のアイテムを選択したときに別ウィンドウで重要な情報を表示したりできます。 9110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 9210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 9310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 9410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyウィンドウの視覚的なコンテンツは、ビュー({@link android.view.View} 基本クラスの派生オブジェクト)の階層として提供されます。各ビューは、ウィンドウ内の特定の矩形領域を制御します。親ビューは、その子となるビューで構成され、それらの子ビューのレイアウトを決定します。リーフ ビュー(階層の最下位に位置するビュー)は、そのビューが制御する矩形領域に表示され、その領域でのユーザーのアクションに対して応答します。つまり、ビューはアクティビティとユーザーが対話する場所です。たとえば、ビューに小さな画像を表示し、ユーザーがその画像をタップしたら何らかのアクションを開始することもできます。Android には、ボタン、テキスト フィールド、スクロール バー、メニュー アイテム、チェックボックスなど、さまざまなビューがあらかじめ用意されています。 9510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 9610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 9710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 9810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyビューの階層は、<code>{@link android.app.Activity#setContentView Activity.setContentView()}</code> メソッドを使用してアクティビティのウィンドウ内に配置します。コンテンツ ビューは、階層のルートとなる View オブジェクトです<i></i>(ビューおよびその階層について詳しくは<a href="{@docRoot}guide/topics/ui/index.html">User Interface</a> のドキュメントをご覧ください)。 9910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 10010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 10110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p><dt><b>サービス</b></dt> 10210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dd>サービスは、視覚的なユーザー インターフェースを持たず、バックグラウンドにおいて明確な終了期限がなくで実行されます。<i></i>たとえば、ユーザーが他の操作をしている間 BGM を再生するサービス、ネットワーク経由でデータをフェッチするサービス、何かを計算してその結果をアクティビティに提供するサービスなどが考えられます。各サービスは、{@link android.app.Service} 基本クラスの拡張です。 10310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 10410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 10510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty典型的な例としては、プレイリストの曲を再生するメディア プレーヤーが挙げられます。プレーヤー アプリケーションは、ユーザーが曲を選んで再生するための 1 つ以上のアクティビティで構成することが予想されますが、ユーザーはプレーヤーを離れて別の操作に移った後も曲を聞いていたいと考えられることから、曲の再生自体をアクティビティで処理するわけにはいきません。音楽の再生を続けるには、メディア プレーヤー アクティビティから、バックグラウンドで実行するサービスを開始します。音楽再生サービスは、それを開始したアクティビティが画面上に見えなくなった後もそのまま実行されます。 10610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 10710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 10810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 10910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyまた、実行中のサービスに接続(バインド)することもできます(実行されていない場合はそのサービスを開始することも可能です)。接続中は、サービスが公開しているインターフェースを使ってサービスと対話できます。音楽再生サービスであれは、このインターフェースを使って一時停止、巻き戻し、停止、再生の再開などの操作を実行できるようにします。 11010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 11110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 11210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 11310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアクティビティや他のコンポーネントと同様に、サービスもアプリケーション プロセスのメイン スレッドで実行します。したがって、サービスによって他のコンポーネントやユーザー インターフェースの実行を妨げられることはなく、時間がかかるタスク(たとえば曲の再生)については、通常は別のスレッドを生成して処理します。詳しくは、<a href="#procthread">プロセスとスレッド</a>をご覧ください。 11410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p></dd> 11510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 11610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dt><b>ブロードキャスト レシーバ</b></dt> 11710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dd>ブロードキャスト レシーバは、ブロードキャストの連絡を受信してそれに対処するだけのコンポーネントです。<i></i>ブロードキャストの多くが元々はシステム コードで、たとえばタイム ゾーンが変更されたこと、電池の残量が少なくなったこと、写真が撮影されたこと、ユーザーが言語設定を変更したことなどを連絡するために使用します。アプリケーションでも、たとえば何らかのデータがデバイスにダウンロードされて利用できるようになったことを、他のアプリケーションにブロードキャストで知らせることができます。 11810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 11910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 12010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアプリケーションでは、重要と思われるすべての連絡に応答できるよう、ブロードキャスト レシーバをいくつでも設定できます。すべてのレシーバは、{@link android.content.BroadcastReceiver} 基本クラスの拡張です。 12110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 12210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 12310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 12410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyブロードキャスト レシーバがユーザー インターフェースを表示することはありません。ただし、受信した情報への応答としてアクティビティを開始したり、{@link android.app.NotificationManager} を使用してユーザーにアラートを送信したりすることはあります。通知の際には、バックライトを点滅させる、バイブレーションを起動する、音を鳴らすなど、さまざまな方法でユーザーの注意を喚起できます。通常は、ステータス バーに永続アイコンを表示し、ユーザーがこれを開いてメッセージを取得できるようにします。 12510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p></dd> 12610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 12710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dt><b>コンテンツ プロバイダ</b></dt> 12810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dd>コンテンツ プロバイダは、アプリケーションのデータを他のアプリケーションでも利用できるようにします。<i></i>データは、ファイル システムや SQLite データベースなど、一般に利用できる方法で格納されていれば使用できます。コンテンツ プロバイダは、{@link android.content.ContentProvider} 基本クラスの拡張です。プロバイダが制御する型のデータを、他のアプリケーションから取得および格納するための標準メソッド セットを実装しています。ただし、これらのメソッドをアプリケーションから直接呼び出すことはできません。代わりに、{@link android.content.ContentResolver} オブジェクトのメソッドを呼び出します。ContentResolver は、すべてのプロバイダと通信でき、プロバイダと連携して関係のあるすべてのプロセス間通信を管理します。 12910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 13010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 13110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyコンテンツ プロバイダの使用方法について詳しくは、<a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>のドキュメントをご覧ください。 13210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p></dd> 13310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 13410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</dl> 13510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 13610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 13710550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyAndroid では、特定のコンポーネントで処理すべきリクエストがあると、そのコンポーネントのアプリケーション プロセスが実行中かどうかを確認(必要に応じてプロセスを開始)し、そのコンポーネントの適切なインスタンスが利用可能かどうかを確認(必要に応じてインスタンスを作成)します。 13810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 13910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 14010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 14110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="actcomp">コンポーネントのアクティブ化: インテント</h3> 14210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 14310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 14410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyコンテンツ プロバイダは、ContentResolver からのリクエストの対象になるとアクティブ化されます。それ以外の 3 つのコンポーネント(アクティビティ、サービス、ブロードキャスト レシーバ)は、インテントと呼ばれる非同期メッセージによってアクティブ化されます。<i></i>インテントは、メッセージのコンテンツを保持する {@link android.content.Intent} オブジェクトです。アクティビティやサービスの場合の Intent オブジェクトの主な役割は、リクエストされているアクションを指名し、その対象となるデータの URI を指定することです。たとえば、ユーザーに画像を表示するためのリクエストや、ユーザーにテキストを編集させるリクエストをアクティビティに伝達できます。ブロードキャスト レシーバの場合は、Intent オブジェクトがこれから通知を行うアクションを指名します。たとえば、カメラのボタンが押されたことを、関係のあるブロードキャスト レシーバに通知できます。 14510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 14610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 14710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 14810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty以下に示すように、コンポーネントのタイプごとに別々のアクティブ化メソッドが用意されています: 14910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 15010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 15110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 15210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 15310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>アクティビティを起動する(または何か新しい処理を実行させる)には、Intent オブジェクトを <code>{@link android.content.Context#startActivity 15410550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyContext.startActivity()}</code> または <code>{@link 15510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyandroid.app.Activity#startActivityForResult 15610550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyActivity.startActivityForResult()}</code> に渡します。応答アクティビティで <code>{@link android.app.Activity#getIntent getIntent()}</code> メソッドを呼び出すと、最初にそのアクティビティが起動されたときのインテントの内容を確認できます。Android によってアクティビティの <code>{@link 15710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyandroid.app.Activity#onNewIntent onNewIntent()}</code> メソッドが呼び出され、アクティビティが後続のインテントに渡されます。 15810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 15910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 16010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty多くの場合、アクティビティから次のアクティビティを開始します。開始するアクティビティから結果が返される場合は、{@code startActivity()} ではなく {@code startActivityForResult()} を呼び出します。たとえば、ユーザーに写真を選択させるアクティビティを開始する場合は、ユーザーによって選択された写真が返されるかもしれません。結果は、呼び出し側のアクティビティの <code>{@link android.app.Activity#onActivityResult 16110550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyonActivityResult()}</code> メソッドに渡した Intent オブジェクトで返されます。 16210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 16310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</li> 16410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 16510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>サービスを開始する(または実行中のサービスに新しい指示を与える)には、<code>{@link 16610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyandroid.content.Context#startService Context.startService()}</code> に Intent オブジェクトを渡します。Android により、サービスの <code>{@link android.app.Service#onStart 16710550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyonStart()}</code> メソッドが呼び出されて Intent オブジェクトが渡されます。</p> 16810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 16910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 17010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty同様に、インテントを <code>{@link 17110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyandroid.content.Context#bindService Context.bindService()}</code> に渡すと、呼び出し側のコンポーネントと対象となるサービスの間の継続中の接続を確立できます。サービスは、<code>{@link android.app.Service#onBind onBind()}</code> 呼び出しで Intent オブジェクトを受け取ります(サービスがまだ開始されていない場合は、必要に応じて {@code bindService()} で開始できます)。たとえば、上で例に挙げた音楽再生サービスとの接続を確立するアクティビティを使用して、ユーザーが再生を操作するための手段(ユーザー インターフェース)を提供できます。アクティビティで {@code bindService()} を呼び出して接続を確立してから、サービスに定義されているメソッドを呼び出して再生を操作します。 17210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 17310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 17410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 17510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyサービスのバインドについては、後ほど<a href="#rpc">リモート プロシージャ コール</a>のセクションで詳しく説明します。 17610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 17710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</li> 17810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 17910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>アプリケーションでブロードキャストを開始するには、<code>{@link 18010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyandroid.content.Context#sendBroadcast(Intent) Context.sendBroadcast()}</code>、<code>{@link android.content.Context#sendOrderedBroadcast(Intent, String) 18110550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyContext.sendOrderedBroadcast()}</code>、<code>{@link 18210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyandroid.content.Context#sendStickyBroadcast Context.sendStickyBroadcast()}</code> などのメソッドのいずれかのバリエーションに Intent オブジェクトを渡します。Android によって <code>{@link 18310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyandroid.content.BroadcastReceiver#onReceive onReceive()}</code> メソッドが呼び出され、関係のあるすべてのブロードキャスト レシーバにインテントが配信されます。</p></li> 18410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 18510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 18610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 18710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 18810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyインテント メッセージについて詳しくは、<a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a> をご覧ください。 18910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 19010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 19110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 19210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="endcomp">コンポーネントの終了</h3> 19310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 19410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 19510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyコンテンツ プロバイダは、ContentResolver からのリクエストに応答している間のみアクティブになります。ブロードキャスト レシーバは、ブロードキャスト メッセージに応答している間のみアクティブになります。つまり、これらのコンポーネントを明示的に終了させる必要はありません。 19610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 19710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 19810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 19910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty一方、アクティビティはユーザー インターフェースを提供します。長い時間をかけてユーザーと会話するためのものであり、待機状態の間も、会話が続いてきる限りはアクティブなままになっている可能性があります。同様に、サービスも長い間実行されたままになる可能性があります。Android には、アクティビティとサービスを以下のような規則的な方法で終了させるためのメソッドが用意されています: 20010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 20110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 20210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 20310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>アクティビティを終了させるには、その <code>{@link android.app.Activity#finish finish()}</code> メソッドを呼び出します。あるアクティビティから {@code startActivityForResult()} で開始した別のアクティビティは、<code>{@link android.app.Activity#finishActivity finishActivity()}</code> を呼び出して終了させることができます。</li> 20410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 20510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>サービスは、その <code>{@link android.app.Service#stopSelf stopSelf()}</code> メソッドを呼び出すか、<code>{@link android.content.Context#stopService Context.stopService()}</code> を呼び出すことで停止できます。</li> 20610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 20710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 20810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 20910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyコンポーネントが、既に利用されていない場合や、Android がよりアクティブな他のコンポーネントにメモリを割り当てる必要がある場合は、システムがコンポーネントを終了させることもあります。このような状況およびその影響については、<a href="#lcycles">コンポーネントのライフサイクル</a>で詳しく説明します。 21010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 21110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 21210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 21310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="manfile">マニフェスト ファイル</h3> 21410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 21510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 21610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアプリケーション コンポーネントを開始するには、Android がそのコンポーネントの存在を認識している必要があります。アプリケーションのコンポーネントは、マニフェスト ファイルで宣言します。このファイルは、アプリケーションのコード、ファイル、リソースなどとともに Android パッケージ({@code .apk} ファイル)にバンドルされます。 21710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 21810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 21910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 22010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyマニフェストは構造化された XML ファイルで、どのアプリケーションでも常に AndroidManifest.xml という名前になります。アプリケーション コンポーネントの宣言以外にも、アプリケーションをリンクさせる必要のあるライブラリ(デフォルトの Android ライブラリを除く)の指定や、アプリケーションに付与されるべき権限の指定などにも使用します。 22110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 22210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 22310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 22410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyしかし、マニフェストの最も重要な役割は、アプリケーションのコンポーネントに関する情報を Android に提供することです。たとえば、アクティビティを次のように宣言できます: 22510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 22610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 22710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<pre><?xml version="1.0" encoding="utf-8"?> 22810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<manifest . . . > 22910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <application . . . > 23010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <activity android:name="com.example.project.FreneticActivity" 23110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty android:icon="@drawable/small_pic.png" 23210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty android:label="@string/freneticLabel" 23310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty . . . > 23410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty </activity> 23510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty . . . 23610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty </application> 23710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</manifest></pre> 23810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 23910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 24010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 要素の {@code name} 属性は、そのアクティビティを実装する {@link android.app.Activity} サブクラスを指名します。{@code icon} および {@code label} 属性には、ユーザーに対して表示するアイコンやラベルが保持されているリソース ファイルを指定します。 24110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 24210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 24310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 24410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyその他のコンポーネントも、サービスは <code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code> 要素、ブロードキャスト レシーバは <code><a href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a></code> 要素、コンテンツ プロバイダは <code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code> 要素を使用して同じような方法で宣言します。マニフェストに宣言されていないアクティビティ、サービス、およびコンテンツ プロバイダは、システムから認識できないため実行されることはありません。ただし、ブロードキャスト レシーバの場合は、マニフェストで宣言する方法と、コード内で {@link android.content.BroadcastReceiver} オブジェクトとして動的に作成し、<code>{@link android.content.Context#registerReceiver Context.registerReceiver()}</code> を呼び出してシステムに登録する方法があります。 24510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 24610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 24710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 24810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyマニフェスト ファイルの作成方法について詳しくは、<a href="{@docRoot}guide/topics/manifest/manifest-intro.html">The AndroidManifest.xml File</a>をご覧ください。 24910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 25010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 25110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 25210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="ifilters">インテント フィルタ</h3> 25310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 25410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 25510550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyIntent オブジェクトでは、対象とするコンポーネントを明示的に指名できます。明示的に指名されている場合、Android はマニフェスト ファイル内の宣言に基づいてコンポーネントを特定してアクティブにします。一方、明示的に指名されていない場合は、そのインテントに応答する上で最適なコンポーネントが選択されます。方法としては、Intent オブジェクトを、その対象となりうるコンポーネントのインテント フィルタと照合します。<i></i>コンポーネントのインテント フィルタは、そのコンポーネントで処理できるインテントの種類を示します。これもコンポーネントに関する重要な情報の 1 つなので、マニフェスト ファイルで宣言します。次に、上に示した例を拡張して 2 つのインテント フィルタを追加したアクティビティを示します: 25610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 25710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 25810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<pre><?xml version="1.0" encoding="utf-8"?> 25910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<manifest . . . > 26010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <application . . . > 26110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <activity android:name="com.example.project.FreneticActivity" 26210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty android:icon="@drawable/small_pic.png" 26310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty android:label="@string/freneticLabel" 26410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty . . . > 26510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <intent-filter . . . > 26610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <action android:name="android.intent.action.MAIN" /> 26710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <category android:name="android.intent.category.LAUNCHER" /> 26810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty </intent-filter> 26910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <intent-filter . . . > 27010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <action android:name="com.example.project.BOUNCE" /> 27110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <data android:mimeType="image/jpeg" /> 27210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <category android:name="android.intent.category.DEFAULT" /> 27310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty </intent-filter> 27410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty </activity> 27510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty . . . 27610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty </application> 27710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</manifest></pre> 27810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 27910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 28010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこの例の 1 つ目のフィルタは、アクション「{@code android.intent.action.MAIN}」とカテゴリ「{@code android.intent.category.LAUNCHER}」を組み合わせた一般的なフィルタです。このフィルタは、アプリケーション ランチャ(ユーザーがデバイス上で起動できるアプリケーションを一覧表示した画面)に、このアクティビティを表示する必要があることを示しています。つまり、このアクティビティはアプリケーションへのエントリ ポイントとして機能し、ユーザーがランチャでそのアプリケーションを選択したときに最初に表示されるということです。 28110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 28210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 28310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 28410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty2 つ目のフィルタでは、アクティビティが特定のタイプのデータに対して実行できるアクションを宣言しています。 28510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 28610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 28710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 28810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyコンポーネントにはインテント フィルタをいくつでも指定でき、それぞれのフィルタで別々の機能を宣言できます。フィルタが 1 つも指定されていないコンポーネントは、そのコンポーネントが対象として明示的に指名されているインテントでのみアクティブにできます。 28910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 29010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 29110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 29210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyコード内で作成して登録したブロードキャスト レシーバの場合、インテント フィルタは {@link android.content.IntentFilter} オブジェクトとして直接インスタンス化されます。それ以外の全てのフィルタは、マニフェストで設定します。 29310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 29410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 29510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 29610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyインテント フィルタについて詳しくは、<a href="{@docRoot}guide/components/intents-filters.html">Intents and Intent Filters</a> をご覧ください。 29710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 29810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 29910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 30010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h2 id="acttask">アクティビティとタスク</h2> 30110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 30210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 30310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty既に説明したように、あるアクティビティから別のアクティビティを開始することができます。これには、別のアプリケーションで定義されているアクティビティも含まれます。たとえば、ユーザーに特定の場所の地図を表示するとします。そのためのアクティビティは既に存在しているので、現在のアクティビティで必要な情報を Intent オブジェクトに格納して {@code startActivity()} に渡すだけで、マップ ビューアに地図を表示できます。ユーザーが [戻る] キーを押すと、画面に元のアクティビティが再表示されます。 30410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 30510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 30610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 30710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこの場合、マップ ビューアは別のアプリケーションで定義されており、そのアプリケーションのプロセスで実行されていますが、ユーザーにとってはマップ ビューアが元のアプリケーションの一部であるかのように感じられます。Android では、両方のアクティビティを同じタスクに組み込むことで、このようなユーザー エクスペリエンスを実現できます。<i></i>簡単に言えば、ユーザーが 1 つの「アプリケーション」と感じるものがタスクです。関連するアクティビティをスタックにまとめたものがタスクです。スタック内のルート アクティビティは、タスクを開始するアクティビティです。通常であれば、ユーザーがアプリケーション ランチャで選択するアクティビティがこれに相当します。スタックの最上位にあるアクティビティは、ユーザーのアクションの焦点となっている実行中のアクティビティです。あるアクティビティから別のアクティビティを開始すると、そのアクティビティが新たにスタックにプッシュされて実行中のアクティビティになります。1 つ前のアクティビティはスタック内に残されています。ユーザーが [[]戻る] キーを押すと、現在のアクティビティがスタックからポップされ、1 つ前のアクティビティが実行中のアクティビティとして再開されます。 30810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 30910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 31010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 31110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyスタックはオブジェクトを保持します。したがって、同じ Activity サブクラスのインスタンス(たとえばマップ インスタンス)を複数開くと、それぞれのインスタンスが別々のエントリになります。スタック内のアクティビティは、プッシュまたはポップされるのみで再配置されることはありません。 31210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 31310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 31410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 31510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyタスクはアクティビティのスタックであり、マニフェスト ファイル内のクラスや要素ではありません。したがって、アクティビティと無関係にタスクの値を設定することはできません。タスクの値は、ルート アクティビティでまとめて設定します。たとえば、次のセクションでは「タスクの親和性」について説明しますが、値はタスクのルート アクティビティの親和性のセットから読み込まれます。 31610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 31710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 31810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 31910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyタスク内のアクティビティは、1 つのユニットとして一緒に移動します。タスク全体(アクティビティ スタック全体)をフォアグラウンドに移動したり、バックグラウンドに移動したりできます。たとえば、現在のタスクは 4 つのアクティビティからなるスタックで、現在のアクティビティの下にアクティビティが 3 つあるとします。ここで、ユーザーが [ホーム] キーを押してアプリケーション ランチャに移動し、新しいアプリケーション(実際には新しいタスク)を選択したとします。<i></i>すると、現在のタスクはバックグラウンドに移動し、新しいタスクのルート アクティビティが表示されます。しばらくして、ユーザーがホーム画面に戻り 1 つ前のアプリケーション(タスク)を選択すると、そのタスクがスタック内の 4 つのアクティビティとともにフォアグラウンドに移動します。ここでユーザーが [戻る] キーを押しても、中断したばかりのアプリケーション(1 つ前のタスクのルート アクティビティ)は表示されません。代わりに、スタックの最上位のアクティビティがポップされ、同じタスクの 1 つ前のアクティビティが表示されます。 32010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 32110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 32210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 32310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアクティビティとタスクの動作としては、ここで説明した動作がデフォルトです。ただし、この動作のほとんどの要素は変更可能です。タスクとアクティビティの関連付けやタスク内でのアクティビティの動作は、アクティビティを開始した Intent オブジェクトのフラグ セットと、マニフェストに指定されているアクティビティの <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 要素の属性セットとの相互作用によって決まります。リクエスト側と応答側の両方が動作に影響を及ぼします。 32410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 32510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 32610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 32710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこの点において、主に使用する Intent フラグは以下のとおりです: 32810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 32910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p style="margin-left: 2em">{@code FLAG_ACTIVITY_NEW_TASK} <br/>{@code FLAG_ACTIVITY_CLEAR_TOP} <br/>{@code FLAG_ACTIVITY_RESET_TASK_IF_NEEDED} <br/>{@code FLAG_ACTIVITY_SINGLE_TOP}</p> 33010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 33110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 33210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyまた、主に使用する {@code <activity>} 属性は以下のとおりです: 33310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 33410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p style="margin-left: 2em">{@code taskAffinity} <br/>{@code launchMode} <br/>{@code allowTaskReparenting} <br/>{@code clearTaskOnLaunch} <br/>{@code alwaysRetainTaskState} <br/>{@code finishOnTaskLaunch}</p> 33510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 33610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 33710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty以降のセクションでは、これらのフラグや属性の役割、相互作用の仕組み、使用する際の留意事項などについて説明します。 33810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 33910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 34010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 34110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="afftask">親和性と新しいタスク</h3> 34210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 34310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 34410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyデフォルトでは、アプリケーション内のすべてのアクティビティは相互に親和性があり、すべてのアクティビティができる限り同じタスクに属そうとします。<i></i>ただし、{@code <activity>} 要素の {@code taskAffinity} 属性を使用して、アクティビティごとに個別の親和性を設定することもできます。つまり、別々のアプリケーションで定義されているアクティビティで親和性を共有したり、同じアプリケーションで定義されているアクティビティに別々の親和性を割り当てたりできるということです。親和性が作用する状況は 2 つあります。1 つはアクティビティを起動する Intent オブジェクトに {@code FLAG_ACTIVITY_NEW_TASK} フラグが含まれている場合、もう 1 つはアクティビティの {@code allowTaskReparenting} 属性が "{@code true}" に設定されている場合です。 34510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 34610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 34710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dl> 34810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dt><code>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</code> フラグ</dt> 34910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dd>既に説明したとおり、新しいアクティビティは、デフォルトでは {@code startActivity()} を呼び出したアクティビティのタスクの一部として起動します。つまり、呼び出し側のアクティビティと同じスタックにプッシュされるということです。しかし、{@code startActivity()} に渡された Intent オブジェクトに {@code FLAG_ACTIVITY_NEW_TASK} フラグが含まれている場合、システムはその新しいアクティビティを別のタスクに収容しようとします。フラグの名前からも判断できますが、ほとんどの場合は新しいタスクが開始されます。ただし常にそうなるとは限りません。既存のタスクに新しいアクティビティと同じ親和性が割り当てられている場合、そのアクティビティはそのタスクの一部として起動します。そうでない場合には、新しいタスクが開始されます。</dd> 35010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 35110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dt><code><a 35210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyhref="{@docRoot}guide/topics/manifest/activity-element.html#reparent">allowTaskReparenting</a></code> 属性</dt> 35310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dd>{@code allowTaskReparenting} 属性が "{@code true}" に設定されているアクティビティは、そのアクティビティと親和性のあるタスクがフォアグラウンドに移ったときに、アクティビティを開始したタスクから親和性のあるタスクに移動できます。たとえば、旅行アプリケーションの一部として、選択された都市の天気予報を表示するアクティビティが定義されているとします。このアクティビティには、同じアプリケーション内の他のアクティビティと同じ親和性(デフォルトの親和性)が割り当てられていますが、その親の割り当てを変更することも可能です。あるアクティビティが天気予報アクティビティを開始すると、その時点では開始側のアクティビティと同じタスクに属した状態になります。しかし、次に旅行アプリケーションがフォアグラウンドに移ると、天気予報アクティビティの割り当てが変更され、旅行アプリケーションのタスクの一部として表示されます。</dd> 35410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</dl> 35510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 35610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 35710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyユーザーから見て複数の「アプリケーション」が 1 つの {@code .apk} ファイルに含まれている場合は、それぞれのアプリケーションに関連付けられているアクティビティに別々の親和性を割り当てることをおすすめします。 35810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 35910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 36010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 36110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="lmodes">起動モード</h3> 36210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 36310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 36410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code> 属性の {@code <activity>} 要素には、以下の 4 種類の起動モードを割り当てることができます: 36510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 36610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 36710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p style="margin-left: 2em">"{@code standard}"(デフォルト モード)<br>"{@code singleTop}"<br>"{@code singleTask}"<br>"{@code singleInstance}"</p> 36810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 36910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 37010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこれらのモードは、それぞれが以下の 4 つの点で異なります: 37110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 37210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 37310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 37410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 37510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><b>インテントに応答するアクティビティをどのタスクに保持するか</b>。"{@code standard}" および "{@code singleTop}" モードの場合は、そのインテントを開始した(つまり <code>{@link android.content.Context#startActivity startActivity()}</code> を呼び出した)タスクに保持されます。ただし、Intent オブジェクトに <code>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</code> フラグが含まれている場合は、前のセクション<a href="#afftask">親和性と新しいタスク</a>で説明したとおり、別のタスクが選択されます。 37610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 37710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 37810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty一方、"{@code singleTask}" および "{@code singleInstance}" モードの場合は、アクティビティが常にタスクのルート アクティビティになります。タスクは定義されており、他のタスクの一部として起動されることはありません。 37910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 38010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 38110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p><b>アクティビティのインスタンスを複数生成できるか</b>。"{@code standard}" または "{@code singleTop}" アクティビティは複数回インスタンス化できます。それらのインスタンスを複数のタスクに割り当てることも、特定のタスクに同じアクティビティの複数のインスタンスを割り当てることも可能です。 38210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 38310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 38410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 38510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty一方、"{@code singleTask}" および "{@code singleInstance}" アクティビティのインスタンスは 1 つに制限されます。これらのアクティビティはタスクのルートに当たります。したがって、これらのタスクの複数のインスタンスがデバイス上に同時に存在することはないということになります。 38610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 38710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 38810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p><b>インスタンスのタスクに他のアクティビティを含めることができるか</b>。"{@code singleInstance}" アクティビティは、そのタスク内の唯一のアクティビティとして単独で動作します。ここから別のアクティビティを開始した場合、そのアクティビティは起動モードに関係なく、あたかもインテントに {@code FLAG_ACTIVITY_NEW_TASK} フラグが含まれているかのように別のタスクで起動します。"{@code singleInstance}" モードと "{@code singleTask}" モードは、これ以外の点ではまったく同じです。</p> 38910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 39010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 39110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty他の 3 つのモードでは、タスクに複数のアクティビティを割り当てることができます。"{@code singleTask}" アクティビティは、常にタスクのルート アクティビティになりますが、同じタスクに割り当てることになる別のアクティビティを開始することができます。"{@code standard}" および "{@code singleTop}" アクティビティのインスタンスは、スタック内のどの位置にでも配置できます。 39210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p></li> 39310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 39410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><b>クラスの新しいインスタンスを起動して新しいインテントを処理するかどうか</b>。デフォルトの "{@code standard}" モードの場合は、新しいインテントに応答するときには必ず新しいインスタンスが作成されます。それぞれのインスタンスで処理するインテントは 1 つのみです。"{@code singleTop}" モードの場合は、クラスの既存のインスタンスが対象タスクのアクティビティ スタックの最上位にあれば、それを再利用して新しいインテントを処理します。スタックの最上位にない場合は再利用されません。代わりに、新しいインスタンスが作成されてスタックにプッシュされ、新しいインテントの処理に使用されます。 39510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 39610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 39710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyたとえば、タスクのアクティビティ スタックに、ルート アクティビティ A とアクティビティ B、C、D が含まれているとします。スタック内のアクティビティの順序は A-B-C-D で D が最上位です。ここに、アクティビティのタイプが D のインテントが届きます。D の起動モードがデフォルトの "{@code standard}" である場合は、そのクラスの新しいインスタンスが起動し、スタックは A-B-C-D-D となります。しかし、D の起動モードが "{@code singleTop}" であれば、スタックの最上位は D なので、新しいインテントは既存のインスタンスによって処理されるはずです。したがって、スタックは A-B-C-D のままとなります。 39810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 39910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 40010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 40110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty一方、届いたインテントのアクティビティ タイプが B だった場合は、B のモードが "{@code standard}" であっても "{@code singleTop}"であっても B の新しいインスタンスが起動します。これは B がスタックの最上位ではないためで、結果としてスタックは A-B-C-D-B となります。 40210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 40310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 40410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 40510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty"{@code singleTask}" または "{@code singleInstance}" アクティビティの場合は、既に説明したとおり同時に複数のインスタンスが存在することはないため、インスタンスは常に新しいインテントを処理することになります。"{@code singleInstance}" アクティビティはスタック内の唯一のアクティビティであるため、常にスタックの最上位、つまりインテントを処理する位置にあります。一方、"{@code singleTask}" アクティビティは、スタック内の上位に他のアクティビティがある場合とない場合があります。上位にアクティビティがある場合、インテントを処理する位置にはないため、そのインテントはドロップされます(インテントがドロップされたとしても、そのインテントが届いたことによって、タスクがフォアグラウンドに移ったままの状態になります)。 40610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 40710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</li> 40810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 40910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 41010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 41110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 41210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty既存のアクティビティで新しいインテントを処理することになった場合は、<code>{@link android.app.Activity#onNewIntent onNewIntent()}</code> の呼び出しによって Intent オブジェクトがアクティビティに渡されます(最初にアクティビティを開始したインテント オブジェクトは <code>{@link android.app.Activity#getIntent getIntent()}</code> を呼び出して取得できます)。 41310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 41410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 41510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 41610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyなお、新しいインテントを処理するためにアクティビティの新しいインスタンスが作成された場合、ユーザーは [[]戻る] キーを押して 1 つ前の状態(1 つ前のアクティビティ)に戻ることができます。しかし、アクティビティの既存のインスタンスで新しいインテントを処理する場合は、[[]戻る] キーを押しても、新しいインテントが届く前にそのインスタンスで処理していた作業に戻ることはできません。 41710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 41810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 41910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 42010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty起動モードについて詳しくは、<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 要素の説明をご覧ください。 42110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 42210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 42310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 42410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="clearstack">スタックのクリア</h3> 42510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 42610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 42710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyユーザーがタスクを長時間放置すると、タスクのルート アクティビティを除くすべてのアクティビティがクリアされます。ユーザーがタスクに戻ると、タスクは以前のように表示されますが、残っているのは最初のアクティビティだけです。つまり、一定の時間が経過していればユーザーは以前の作業を放棄していて、新しい作業をするためにそのタスクに戻ってきたと考えるわけです。 42810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 42910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 43010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 43110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこれがデフォルトです。この動作を変更したい場合は、以下のアクティビティ属性を使用します: 43210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 43310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 43410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dl> 43510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dt><code><a 43610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyhref="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code> 属性</dt> 43710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dd>タスクのルート アクティビティでこの属性を "{@code true}" に設定すると、上で説明したデフォルトの動作は発生しません。長時間経過しても、タスク内のすべてのアクティビティはそのまま残されます。</dd> 43810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 43910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dt><code><a 44010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyhref="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code> 属性</dt> 44110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dd>タスクのルート アクティビティでこの属性を "{@code true}" に設定した場合、ユーザーがいったんタスクを離れると、戻ったときにはルートを含むすべてのアクティビティがクリアされています。つまり、{@code alwaysRetainTaskState} の正反対の動作になります。ユーザーが一瞬でもタスクを離れると、最初の状態からやり直すことになります。</dd> 44210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 44310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dt><code><a 44410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyhref="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code> 属性</dt> 44510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<dd>この属性は {@code clearTaskOnLaunch} に似ていますが、タスク全体ではなく単一のアクティビティに作用します。また、ルート アクティビティを含むどのアクティビティもクリアの対象となりえます。この属性が "{@code true}" に設定されたアクティビティは、現在のセッションの間のみタスクの一部を形成します。ユーザーがいったんそのタスクから離れてから、再度タスクに戻ると、このアクティビティはクリアされています</dd> 44610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</dl> 44710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 44810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 44910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアクティビティをスタックから削除する方法は他にもあります。Intent オブジェクトに <code>{@link 45010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyandroid.content.Intent#FLAG_ACTIVITY_CLEAR_TOP FLAG_ACTIVITY_CLEAR_TOP}</code> フラグが含まれており、そのインテントを処理すべきタイプのアクティビティのインスタンスが対象タスクのスタック内に存在する場合は、そのインスタンスがスタックの最上位になってインテントに応答できるよう、それより上位のアクティビティはすべてクリアされます。指定されたアクティビティの起動モードが "{@code standard}" である場合は、そのアクティビティもスタックから削除され、新しいインスタンスが起動してインテントを処理します。起動モード "{@code standard}" では、新しいインテントを処理する際、常に新しいインスタンスが作成されるためです。 45110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 45210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 45310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 45410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty{@code FLAG_ACTIVITY_CLEAR_TOP} は、ほとんどの場合 {@code FLAG_ACTIVITY_NEW_TASK} と組み合わせて使用します。これらのフラグを組み合わせると、別のタスクに既に存在しているアクティビティを探し、それをインテントに応答できる位置に配置できます。 45510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 45610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 45710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 45810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="starttask">タスクの開始</h3> 45910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 46010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 46110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアクティビティをタスクのエントリ ポイントとして設定するには、アクションとして "{@code android.intent.action.MAIN}"、カテゴリとして "{@code android.intent.category.LAUNCHER}" を指定したインテント フィルタをアクティビティに追加します(このタイプのフィルタの例については、<a href="#ifilters">インテント フィルタ</a>をご覧ください)。このタイプのフィルタを追加すると、アクティビティのアイコンとラベルがアプリケーション ランチャに表示されます。これにより、ユーザーがタスクを起動するための手段を提供できるだけでなく、起動後はいつでもそのタスクに戻れるようにすることができます。 46210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 46310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 46410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 46510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこの 2 番目の機能、つまりユーザーがいったんタスクを離れても後で戻ることができるようにする点が重要です。この理由から、アクティビティに {@code MAIN} と {@code LAUNCHER} フィルタが指定されている場合は、必ずタスクが開始される起動モード("{@code singleTask}" または "{@code singleInstance}")を使用する必要があります。たとえば、このフィルタを指定しなかった場合を考えてみましょう。インテントが "{@code singleTask}" アクティビティを起動し、新しいタスクが開始され、ユーザーがしばらくの間このタスクで作業を行います。その後、ユーザーが [ホーム] キーを押したとします。ホーム画面が表示され、先ほどのタスクはバックグラウンドに移動します。しかし、このタスクはアプリケーション ランチャには表示されていないため、ユーザーがタスクに戻るための手段がありません。 46610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 46710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 46810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 46910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty{@code FLAG_ACTIVITY_NEW_TASK} フラグにも、これと同じような難しさがあります。このフラグを指定したアクティビティでは、新しいタスクを開始した後にユーザーが [ホーム] キーを押してそのタスクを離れた場合に備え、タスクに戻るための手段を用意しておく必要があります。一部のエンティティ(たとえば通知マネージャ)は、アクティビティを常に外部タスクとして開始します。エンティティの一部として開始することはないため、{@code startActivity()} に渡すインテントには必ず {@code FLAG_ACTIVITY_NEW_TASK} を指定します。外部エンティティから呼び出すことのできるアクティビティでこのフラグが使用されている可能性がある場合は、開始されたタスクにユーザーが戻るための手段を別途提供するようにしてください。 47010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 47110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 47210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 47310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyユーザーがアクティビティに戻ることができるようにしない場合は、{@code <activity>} 要素の {@code finishOnTaskLaunch} を "{@code true}" に設定します。詳しくは、<a href="#clearstack">スタックのクリア</a>をご覧ください。 47410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 47510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 47610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 47710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h2 id="procthread">プロセスとスレッド</h2> 47810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 47910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 48010550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyAndroid では、最初のアプリケーション コンポーネントを実行する必要が生じると、そのための Linux プロセスを単一の実行スレッドで開始します。デフォルトでは、アプリケーションのすべてのコンポーネントがそのプロセスとスレッドで実行されます。 48110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 48210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 48310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 48410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyただし、コンポーネントが他のプロセスで実行されるようにしたり、特定のプロセスに使用する追加スレッドを生成したりすることも可能です。 48510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 48610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 48710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 48810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="procs">プロセス</h3> 48910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 49010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 49110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyコンポーネントを実行するプロセスは、マニフェスト ファイルで管理します。コンポーネントの各要素({@code <activity>}、{@code <service>}、{@code <receiver>}、および {@code <provider>})には {@code process} 属性があり、そのコンポーネントをどのプロセスで実行すべきかを指定できるようになっています。これらの属性の設定によって、それぞれのコンポーネントを専用のプロセスで実行したり、一部のコンポーネントだけでプロセスを共有したりできます。また、別々のアプリケーションのコンポーネントが、同じプロセスで実行されるように設定することもできます。この場合は、それらのアプリケーションが同じ Linux ユーザー ID を共有し、同じ認証機関によって署名されている必要があります。{@code <application>} 要素にも {@code process} 属性があり、すべてのコンポーネントに適用されるデフォルト値を設定できます。 49210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 49310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 49410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 49510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyすべてのコンポーネントは指定されたプロセスのメイン スレッドでインスタンス化され、コンポーネントに対するシステム コールはそのスレッドからディスパッチされます。1 つのインスタンスに対して、複数のスレッドが作成されることはありません。したがって、システム コールに応答するメソッド(たとえば、後ほど<a href="#lcycles">コンポーネント ライフサイクル</a>で説明するライフサイクル通知や、ユーザーのアクションを報告する <code>{@link android.view.View#onKeyDown View.onKeyDown()}</code> のようなメソッド)は、常にそのプロセスのメイン スレッドで実行されます。つまり、コンポーネントがシステムから呼び出されたときに、プロセス内の他のコンポーネントの実行を妨げないよう、実行に時間がかかる処理や他の妨げになることの多い処理(ネットワーク処理、ループ計算など)をできる限り避ける必要があるということです。時間がかかる処理には別のスレッドを生成できます。詳しくは、次の<a href="#threads">スレッド</a> セクションをご覧ください。 49610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 49710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 49810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 49910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty状況によっては、Android がプロセスを終了させるべきと判断する場合があります。たとえば、メモリが不足してきた場合や、他のプロセスでユーザーにすばやく応答する必要がある場合です。プロセスが終了すると、そのプロセス内で実行されているアプリケーション コンポーネントは破棄されます。それらのコンポーネントで処理する作業がもう一度発生すると、そのためのプロセスが再び開始されます。 50010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 50110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 50210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 50310550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyAndroid では、どのプロセスを終了させるかを判断するため、ユーザーにとっての相対的な重要度を重み付けして管理します。たとえば、アクティビティがまだ画面に表示されているプロセスを終了させるよりも、アクティビティが画面に表示されていないプロセスを終了させる方が合理的です。したがって、プロセスを終了させるかどうかは、そのプロセスで実行されているコンポーネントの状態に応じて判断されるということです。コンポーネントの状態については、後ほど<a href="#lcycles">コンポーネントのライフサイクル</a>で詳しく説明します。 50410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 50510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 50610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 50710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="threads">スレッド</h3> 50810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 50910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 51010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアプリケーションを単一のプロセスに限定したとしても、バックグラウンドでの処理にスレッドが必要になることはよくあります。ユーザー インターフェースはユーザーのアクションに対して常にすばやく応答できなければならないため、アクティビティをホストするスレッドで、ネットワーク ダウンロードのような時間のかかる処理を一緒にホストしないようにする必要があります。すぐに完了しない可能性のあるすべての処理は、別のスレッドに割り当てるようにしてください。 51110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 51210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 51310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 51410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyスレッドは、標準の Java {@link java.lang.Thread} オブジェクトを使用してコード内で作成します。Android には、スレッドを管理するための便利なクラスが数多く用意されています。たとえば、スレッド内でメッセージ ループを実行するための {@link android.os.Looper}、メッセージを処理するための {@link android.os.Handler}、メッセージ ループでスレッドを設定するための {@link android.os.HandlerThread} などがあります。 51510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 51610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 51710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 51810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="rpc">リモート プロシージャ コール</h3> 51910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 52010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 52110550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyAndroidは軽量な仕組みのリモート・プロシージャ・コール (RPC) を採用しています。RPC とは、メソッドをローカルで呼び出しますが、実行はリモート(別のプロセス)で行い、その結果を呼び出し側に返します。そのためには、メソッド呼び出しとそれに付随するデータをオペレーティングシステムが解釈できるレベルまで分解してから、それらをローカルのプロセスとアドレス空間からリモートのプロセスとアドレス空間に転送し、リモートで呼び出しを再構築する必要があります。戻り値は、反対方向に転送しなければなりません。Android にはこの処理を行うためのコードがすべて用意されているため、RPC インターフェースを定義して実装するだけで RPC を利用できます。 52210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 52310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 52410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 52510550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyRPC インターフェースに含めることができるのはメソッドのみです。すべてのメソッドは、戻り値がない場合でも同期的に実行されます(つまり、リモート メソッドが完了するまでローカル メソッドがブロックされます)。 52610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 52710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 52810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 52910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこのメカニズムを簡単に説明すると次のようになります。まず、シンプルなインターフェース定義言語(IDL)を使用して、実装したい RPC インターフェースを宣言します。<code><a href="{@docRoot}guide/components/aidl.html">aidl</a></code> ツールにより、RPC インターフェースの宣言から Java インターフェース定義が生成されます。この定義は、ローカルとリモートの両方のプロセスで使用する必要があります。定義には、次の図に示すように 2 つの内部クラスが含まれています: 53010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 53110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 53210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p style="margin-left: 2em"> 53310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<img src="{@docRoot}images/binder_rpc.png" alt="RPC のメカニズム" /> 53410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 53510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 53610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 53710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこれらの内部クラスには、IDL で宣言したインターフェースのリモート プロシージャ コールを管理するために必要なコードがすべて含まれています。どちらの内部クラスも {@link android.os.IBinder} インターフェースを実装します。一方の内部クラスは、ローカルのシステムで内部的に使用しますが、記述するコードでは無視しても構いません。もう一方の内部クラスはスタブと呼ばれ、{@link android.os.Binder} クラスを拡張します。スタブには、IPC(プロセス間通信)呼び出しを発生させるための内部コードに加え、IDL で宣言した RPC インターフェース内のメソッドの宣言が含まれます。これらのメソッドを実装するには、図に示すようにスタブをサブクラス化します。2つの内部クラスのうちの一方は、システムがローカルかつ内部的に使用するので、開発者が記述するコードでは無視してかまいません。... リモート側では、図のようにスタブをサブクラス化して、これらのメソッドを実装する必要があります。 53810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 53910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 54010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 54110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 通常、リモート プロセスはサービスで管理します。サービスなら、プロセスや他のプロセスへの接続に関する情報をシステムに伝えることができるからです。サービスには、{@code aidl} ツールで生成されたインターフェース ファイルと、RPC メソッドを実装するスタブ サブクラスの両方を持たせることになります。サービスのクライアントには、{@code aidl} ツールで生成されたインターフェース ファイルのみを持たせます。 54210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 54310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 54410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 54510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty以下に、サービスとそのクライアントの間の接続がどのように設定されるかを示します: 54610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 54710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 54810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 54910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>サービスのクライアント(ローカル側)には <code>{@link android.content.ServiceConnection#onServiceConnected 55010550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyonServiceConnected()}</code> および<code>{@link android.content.ServiceConnection#onServiceDisconnected 55110550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyonServiceDisconnected()}</code> メソッドが実装されているため、リモート サービスとの接続が確立されたときや切断されたときには通知を受けることができます。通知があり次第、<code>{@link android.content.Context#bindService bindService()}</code> を呼び出して接続を設定します。 55210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</li> 55310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 55410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li> 55510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyサービスの <code>{@link android.app.Service#onBind onBind()}</code> メソッドは、受け取ったインテント({@code bindService()} に渡されたインテント)に応じて、接続を承認または拒否するために実装します。接続が承認されると、接続を承認するのであれば、スタブ サブクラスのインスタンスを返します。 55610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</li> 55710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 55810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>サービスが接続を承認すると、Android がクライアントの {@code onServiceConnected()} メソッドを呼び出し、IBinder オブジェクト(サービスが管理するスタブ サブクラスのプロキシ)を渡します。クライアントは、このプロキシを介してリモートサービスを呼び出すことができます。 55910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</li> 56010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 56110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 56210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 56310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyここでは、説明を簡単にするため、RPC メカニズムの細かい点は省略しています。詳しくは、<a href="{@docRoot}guide/components/aidl.html">Designing a Remote Interface Using AIDL</a>、および {@link android.os.IBinder IBinder} クラスの説明をご覧ください。 56410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 56510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 56610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 56710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="tsafe">スレッドセーフなメソッド</h3> 56810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 56910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 57010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty状況によっては実装したメソッドが複数のスレッドから呼び出されることもあるため、スレッドセーフな記述を心掛ける必要があります。 57110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 57210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 57310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 57410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty前のセクションで説明した RPC のようにメソッドをリモートで呼び出すことができる場合は、このような状況が特に発生しやすくなります。IBinder オブジェクトに実装されているメソッドを IBinder と同じプロセスから呼び出すと、そのメソッドは呼び出し側のスレッドで実行されます。一方、別のプロセスからメソッドを呼び出した場合は、プロセスのメイン スレッドではなく、IBinder と同じプロセス内に保持されているスレッドのプールから選択されたスレッドで実行されます。たとえば、サービスの {@code onBind()} メソッドはそのサービスのプロセスのメイン スレッドから呼び出されるのに対し、{@code onBind()} から返されたオブジェクトに実装されているメソッド(たとえば RPC メソッドを実装するスタブ サブクラス)はプール内のスレッドから呼び出されます。サービスには複数のクライアントを割り当てることができるため、複数のプール スレッドを同じ IBinder に同時に割り当てることも可能です。したがって、IBinder メソッドはスレッドセーフになるように実装する必要があります。 57510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 57610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 57710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 57810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty同様に、コンテンツ プロバイダも別のプロセスからのデータ リクエストを受け取ることができます。ContentResolver および ContentProvider クラスはプロセス間通信の管理の詳細を隠蔽しますが、それらのリクエストに応答する ContentProvider メソッド(<code>{@link android.content.ContentProvider#query query()}</code>、<code>{@link android.content.ContentProvider#insert insert()}</code>、<code>{@link android.content.ContentProvider#delete delete()}</code>、<code>{@link android.content.ContentProvider#update update()}</code>、および <code>{@link android.content.ContentProvider#getType getType()}</code> メソッド)は、プロセスのメイン スレッドではなく、コンテンツ プロバイダのプロセス内のスレッドのプールから呼び出されます。これらのメソッドを同時に呼び出すことのできるメソッドの数に制限はありません。したがって、これらのメソッドもスレッドセーフになるように実装する必要があります。 57910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 58010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 58110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 58210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h2 id="lcycles">コンポーネントのライフサイクル</h2> 58310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 58410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 58510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアプリケーション コンポーネントにはライフサイクルがあります。ライフサイクルは、インテントへ応答することでのインスタンス化で始まり、そのインスタンスの破棄で終わります。この間、コンポーネントがアクティブなときとアクティブでないときがあり、アクティビティであればユーザーから見えるときと見えないときがあります。このセクションでは、アクティビティ、サービス、およびブロードキャスト レシーバのライフサイクルについて説明します。具体的には、それぞれがライフタイムの間に取ることのできる状態、状態の遷移を通知する方法、およびそれらの状態が、コンポーネントを実行しているプロセスが終了させられたり、インスタンスが破棄されたりする可能性への影響などについて説明します。 58610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 58710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 58810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 58910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="actlife">アクティビティのライフサイクル</h3> 59010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 59110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p>アクティビティは、基本的に以下の 3 つの状態を取ります:</p> 59210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 59310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 59410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li> 状態がアクティブまたは実行中のアクティビティは、画面のフォアグラウンドに表示されている(つまり現在のタスクのアクティビティ スタックの最上位にある)アクティビティです。<em></em><em></em>これが、ユーザーのアクションの焦点となっているアクティビティです。</li> 59510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 59610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>状態が一時停止のアクティビティは、ユーザーのアクションの焦点から外れていますが、まだユーザーから見ることのできるアクティビティです。<em></em>つまり、それよりも前面に他のアクティビティが表示されていますが、そのアクティビティが透明か全画面表示でないかのどちらかで、一時停止しているアクティビティの一部が見えている状態です。一時停止しているアクティビティは、完全に動作しています(すべての状態やメンバー情報は保持されており、ウィンドウ マネージャにアタッチされたままになっています)。ただし、メモリが極端に不足した場合は、システムによって強制終了させられる可能性があります。</p></li> 59710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 59810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>状態が停止のアクティビティは、別のアクティビティに隠されて完全に見えなくなったアクティビティです。<em></em>すべての状態とメンバー情報はまだ保持しています。しかし、もうユーザーに対して表示されていないため、他でメモリが必要な場合は強制終了させられる可能性が高いアクティビティです。</p></li> 59910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 60010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 60110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 60210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyシステムが一時停止または停止しているアクティビティをメモリから削除する場合は、アクティビティの {@link android.app.Activity#finish finish()} メソッドを呼び出して終了を要求するか、単純のそのプロセスを強制終了します。そのアクティビティをもう一度ユーザーに表示する際は、完全に再起動して以前の状態に復元する必要があります。 60310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 60410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 60510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 60610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアクティビティがある状態から別の状態に遷移すると、以下の protected メソッドに対する呼び出しによって変更が通知されます: 60710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 60810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 60910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p style="margin-left: 2em">{@code void onCreate(Bundle <i>savedInstanceState</i>)} <br/>{@code void onStart()} <br/>{@code void onRestart()} <br/>{@code void onResume()} <br/>{@code void onPause()} <br/>{@code void onStop()} <br/>{@code void onDestroy()}</p> 61010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 61110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 61210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこれらのメソッドはすべて、状態が変化したときに適切な処理を行うためにオーバーライドできるフックです。オブジェクトが初めてインスタンス化されたときに初期設定を行うため、すべてのアクティビティには <code>{@link android.app.Activity#onCreate onCreate()}</code> を実装する必要があります。多くのアクティビティには、データの変更をコミットするための <code>{@link android.app.Activity#onPause onPause()}</code> も実装します。これを実装しない場合は、何らかの方法でユーザーとの対話を停止できるようにしておく必要があります。 61310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 61410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 61510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<div class="sidebox-wrapper"> 61610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<div class="sidebox"> 61710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h2>スーパークラスの呼び出し</h2> 61810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 61910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyどのアクティビティ ライフサイクル メソッドの実装でも、必ず最初にスーパークラス バージョンを呼び出す必要があります。次に例を示します: 62010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 62110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 62210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<pre>protected void onPause() { 62310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty super.onPause(); 62410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty . . . 62510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty}</pre> 62610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</div> 62710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</div> 62810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 62910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 63010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 63110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこれら 7 つのメソッドを使用すると、アクティビティのライフサイクル全体を定義できます。これらを実装することで、ネストされた 3 つのループからなるアクティビティのライフサイクルを監視できます: 63210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 63310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 63410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 63510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>アクティビティの<b>ライフタイム全体</b>は、<code>{@link android.app.Activity#onCreate onCreate()}</code> が初めて呼び出されたときに始まり、最後に <code>{@link android.app.Activity#onDestroy}</code> が呼び出されたときに終了します。アクティビティは、{@code onCreate()} で「全体的」な状態のすべての初期設定を行い、{@code onDestroy()} 残っていたリソースをすべて解放します。たとえば、ネットワークからのデータのダウンロードをバックグラウンドで実行するスレッドは、{@code onCreate()} で作成され、{@code onDestroy()} で停止します。</li> 63610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 63710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>アクティビティの<b>可視ライフタイム</b>は、<code>{@link android.app.Activity#onStart onStart()}</code> の呼び出しで始まり、対応する <code>{@link android.app.Activity#onStop onStop()}</code> の呼び出しで終了します。このライフタイムの間は、ユーザーが画面上でそのアクティビティを見ることができます。ただし、アクティビティがフォアグラウンドにない場合や、ユーザーと対話していない場合もあります。これらの 2 つのメソッドの間は、ユーザーに対してアクティビティを表示するために必要なリソースを確保できます。たとえば、{@code onStart()} で {@link android.content.BroadcastReceiver} を登録して UI に影響する変化を監視し、表示しているアクティビティがユーザーから見えなくなったら {@code onStop()} で登録を解除できます。{@code onStart()} および {@code onStop()} メソッドは、アクティビティがユーザーから見え隠れするたびに繰り返し呼び出すことができます。</p></li> 63810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 63910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>アクティビティの<b>フォアグラウンド ライフタイム</b>は、<code>{@link android.app.Activity#onResume onResume()}</code> の呼び出しで始まり、対応する <code>{@link android.app.Activity#onPause onPause()}</code> の呼び出しで終了します。フォアグラウンド ランタイムの間は、このアクティビティが他のどのアクティビティよりも前面に表示され、ユーザーと対話しています。アクティビティは、一時停止状態と再開状態の間を頻繁に遷移します。たとえば、デバイスがスリープ状態になるときや新しいアクティビティを開始するときには {@code onPause()} が呼び出され、アクティビティの結果や新しいインテントが届いたときには {@code onResume()} が呼び出されます。したがって、これらのメソッドを記述する際は、できるだけ軽量化しておく必要があります。</p></li> 64010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 64110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 64210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 64310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty次の図に、これらのループとアクティビティの遷移経路を示します。色の付いた楕円は、アクティビティが取ることのできる主な状態です。長方形は、アクティビティが状態間を遷移するときに処理を実行するために実装できるコールバック メソッドを表します。 64410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 64510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 64610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p style="margin-left: 2em"><img src="{@docRoot}images/activity_lifecycle.png" 64710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyalt="Android のアクティビティ ライフサイクルの状態遷移図" /></p> 64810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 64910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 65010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty次の表では、各メソッドについて詳しく説明し、ライフサイクル全体における位置付けを示します: 65110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 65210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 65310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<table border="2" width="85%" frame="hsides" rules="rows"> 65410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<colgroup align="left" span="3"></colgroup> 65510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<colgroup align="left"></colgroup> 65610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<colgroup align="center"></colgroup> 65710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<colgroup align="center"></colgroup> 65810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 65910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<thead> 66010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<tr><th colspan="3">メソッド</th> <th>説明</th> <th>強制終了</th> <th>次</th></tr> 66110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</thead> 66210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 66310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<tbody> 66410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<tr> 66510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td> 66610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td>アクティビティが初めて作成されるときに呼び出されます。通常の静的な設定(ビューの作成、リストへのデータのバインドなど)は、すべてのこのメソッドで行う必要があります。このアクティビティの 以前の状態が保存されていた場合、このメソッドにはその状態を保持している Bundle オブジェクトが引数として(詳しくは、後述の<a href="#actstate">アクティビティの状態の保存</a>をご覧ください)。 66710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <p>この後には、必ず {@code onStart()} が呼び出されます。</p></td> 66810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center">不可</td> 66910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center">{@code onStart()}</td> 67010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</tr> 67110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 67210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<tr> 67310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td rowspan="5" style="border-left: none; border-right: none;"> </td> 67410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td colspan="2" align="left"><code>{@link android.app.Activity#onRestart 67510550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyonRestart()}</code></td> 67610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td>アクティビティが停止した後、それをもう一度開始する直前に呼び出されます。 67710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <p>この後には、必ず {@code onStart()} が呼び出されます。</p></td> 67810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center">不可</td> 67910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center">{@code onStart()}</td> 68010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</tr> 68110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 68210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<tr> 68310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td> 68410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td>アクティビティがユーザーから見えるようになる直前に呼び出されます。 68510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <p>その後、アクティビティがフォアグラウンドに表示された場合は {@code onResume()} が、他のアクティビティの後ろに隠れた場合は {@code onStop()} が呼び出されます。</p></td> 68610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center">不可</td> 68710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center">{@code onResume()} <br/>または<br/>{@code onStop()}</td> 68810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</tr> 68910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 69010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<tr> 69110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td rowspan="2" style="border-left: none;"> </td> 69210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td> 69310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td>アクティビティがユーザーとの対話を開始する直前に呼び出されます。この時点で、アクティビティはアクティビティ スタックの最上位にあり、ユーザーからの入力はこのアクティビティに対して行われます。 69410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <p>この後には、必ず {@code onPause()} が呼び出されます。</p></td> 69510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center">不可</td> 69610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center">{@code onPause()}</td> 69710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</tr> 69810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 69910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<tr> 70010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td> 70110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td>システムが別のアクティビティを開始しようとしているときに呼び出されます。このメソッドは、保存されていない変更を永続データにコミットする場合や、アニメーションのように CPU を大量に消費する処理を停止する場合に使用するのが一般的です。このメソッドが終了するまでは次のアクティビティが開始されたないため、できる限り短時間で実行できるようにしておく必要があります。 70210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <p>その後、アクティビティがフォアグラウンドに戻った場合は {@code onResume()} が、ユーザーから見えなくなった場合は {@code onStop()} が呼び出されます。</td> 70310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center"><strong style="color:#800000">可能</strong></td> 70410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center">{@code onResume()} <br/>または<br/>{@code onStop()}</td> 70510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</tr> 70610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 70710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<tr> 70810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td> 70910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td>アクティビティがユーザーから見えなくなったときに呼び出されます。見えなくなる状況としては、アクティビティが破棄された場合や、再開された別のアクティビティ(既存か新規かを問わず)によって隠された場合が考えられます。 71010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <p>その後、アクティビティがユーザーとの対話に戻った場合は {@code onRestart()} が、アクティビティが完全に終了する場合は {@code onDestroy()} が呼び出されます。</p></td> 71110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center"><strong style="color:#800000">可能</strong></td> 71210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center">{@code onRestart()} <br/>または<br/>{@code onDestroy()}</td> 71310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</tr> 71410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 71510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<tr> 71610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy 71710550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyonDestroy()}</code></td> 71810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td>アクティビティが破棄される前に呼び出されます。これが、アクティビティが受け取る最後の呼び出しとなります。このメソッドが呼び出される状況としては、アクティビティが完了する場合(<code>{@link android.app.Activity#finish 71910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty finish()}</code> が呼び出されたとき)や、システムが領域を確保するために一時的にそのアクティビティのインスタンスを破棄する場合が考えられます。これらの 2 つの状況は、<code>{@link 72010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty android.app.Activity#isFinishing isFinishing()}</code> メソッドを使用して識別できます。</td> 72110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center"><strong style="color:#800000">可能</strong></td> 72210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty <td align="center"><em>なし</em></td> 72310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</tr> 72410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</tbody> 72510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</table> 72610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 72710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 72810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty表の<b>強制終了</b>列に注目してください。この列は、メソッドが終了した後であれば、システムがアクティビティのコードの別の行を実行することなくいつでもアクティビティを実行しているプロセスを強制終了できるかどうかを示しています。<em></em>{@code onPause()}、{@code onStop()}、および {@code onDestroy()} メソッドの 3 つは「可能」となっています。1 番目に挙げた {@code onPause()} だけは、プロセスが強制終了する前に必ず呼び出されます。{@code onStop()} と {@code onDestroy()} は、必ず呼び出されるとは限りません。したがって、永続データ(たとえばユーザーによる編集)をストレージに書き込む際は {@code onPause()} を使用する必要があります。 72910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 73010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 73110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 73210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<b>強制終了</b>列が「不可」になっているメソッドは、それらが呼び出された瞬間から、アクティビティを実行しているプロセスを保護して強制終了されないようにします。したがって、アクティビティが強制終了可能な状態にあるのは、たとえば {@code onPause()} が返されてから {@code onResume()} が呼び出されるまでの間ということです。その後は、もう一度 {@code onPause()} が返されるまで、強制終了できる状態には戻りません。 73310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 73410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 73510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 73610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty後述の<a href="#proclife">プロセスとライフサイクル</a>のセクションで詳しく説明しますが、ここでの定義で技術的には「強制終了可能」でないアクティビティでも、システムによって強制終了させられる可能性はありますが、他に利用できるリソースがないなど、極端に急を要する場合に限られます。 73710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 73810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 73910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 74010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h4 id="actstate">アクティビティの状態の保存</h4> 74110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 74210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 74310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyメモリ不足を補うためにユーザーではなくシステムがアクティビティを終了させた場合には,ユーザがそのアクティビティに戻ったときに、以前の状態のままであることを期待するでしょう。 74410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 74510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 74610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 74710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアクティビティが強制終了させられる前の状態を保存しておきたい場合は、アクティビティに <code>{@link android.app.Activity#onSaveInstanceState 74810550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyonSaveInstanceState()}</code> メソッドを実装します。このメソッドは、アクティビティが破棄されやすい状態になる前(つまり {@code onPause()} が呼び出される前)に呼び出されます。その際、アクティビティの動的な状態を名前/値ペアとして記録できる {@link android.os.Bundle} オブジェクトが渡されます。アクティビティがもう一度開始されると、Bundle は {@code onCreate()} だけでなく、{@code onStart()} の後に呼び出される <code>{@link 74910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyandroid.app.Activity#onRestoreInstanceState onRestoreInstanceState()}</code> メソッドにも渡され、保存されている状態をそのどちらかまたは両方で復元できます。 75010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 75110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 75210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 75310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty{@code onSaveInstanceState()} および {@code onRestoreInstanceState()} メソッドは、これまでに説明した {@code onPause()} などとは異なり、ライフサイクル メソッドではありません。これらのメソッドは、常に呼び出されるわけではありません。たとえば、{@code onSaveInstanceState()} は、システムによってアクティビティが破棄しやすい状態にされる前には呼び出されますが、ユーザーのアクション(たとえば [[]戻る] キー)によってインスタンスが実際に破棄されるときには呼び出されません。そのような場合は、ユーザーがそのアクティビティに戻ることを想定する必要はないため、状態を保存する理由がないのです。 75410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 75510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 75610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 75710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty{@code onSaveInstanceState()} は常に呼び出されるとは限らないため、アクティビティの一時的な状態を記録する目的のみに使用し、永続データの格納には使用しないようにしてください。この目的には {@code onPause()} を使用します。 75810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 75910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 76010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 76110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h4 id="coordact">アクティビティの協調</h4> 76210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 76310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 76410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyあるアクティビティが別のアクティビティを開始すると、両方のアクティビティのライフサイクル状態が遷移します。一方が一時停止または停止し、もう一方が開始されます。場合によっては、これらの協調させる必要があります。 76510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 76610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 76710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 76810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyライフサイクルのコールバックの順序は明確に定義されており、特に 2 つのアクティビティが同じプロセス内に存在する場合は次のようになります: 76910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 77010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 77110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ol> 77210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>現在のアクティビティの {@code onPause()} メソッドが呼び出されます。</li> 77310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 77410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>続いて、開始されるアクティビティの {@code onCreate()}、{@code onStart()}、および {@code onResume()} メソッドが順番に呼び出されます。</li> 77510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 77610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>その後、開始されたアクティビティが画面上で見えなくなると、その {@code onStop()} メソッドが呼び出されます。</li> 77710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ol> 77810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 77910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 78010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="servlife">サービスのライフサイクル</h3> 78110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 78210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 78310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyサービスは、以下の 2 つの方法で使用できます: 78410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 78510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 78610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 78710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>いったん開始したら、停止させられる(または自ら停止する)まで実行し続けることができます。このモードでは、<code>{@link android.content.Context#startService Context.startService()}</code> が呼び出されて開始し、<code>{@link android.content.Context#stopService Context.stopService()}</code> 呼び出されて停止します。サービス自体が <code>{@link android.app.Service#stopSelf() Service.stopSelf()}</code> または <code>{@link android.app.Service#stopSelfResult Service.stopSelfResult()}</code> を呼び出して停止することもできます。サービスの開始時に {@code startService()} が何度呼び出されたとしても、{@code stopService()} を一度呼び出せばサービスは停止します。</li> 78810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 78910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>サービスで定義されているインターフェースをエクスポートし、これを介してプログラム的に操作できます。クライアントから Service オブジェクトへの接続を確立し、その接続を使用してサービスにアクセスします。接続は、<code>{@link android.content.Context#bindService Context.bindService()}</code> を呼び出して確立し、<code>{@link android.content.Context#unbindService Context.unbindService()}</code> でサービスを開始します。複数のクライアントが同じサービスにバインドすることも可能です。サービスがまだ開始されていなかった場合は,必要に応じて {@code bindService()} で開始できます。 79010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p></li> 79110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 79210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 79310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 79410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこれら 2 つのモードは、完全に分離されているわけではありません。{@code startService()} で開始されたサービスにバインドすることも可能です。たとえば、再生する曲を指定した Intent オブジェクトで {@code startService()} を呼び出して音楽再生サービスを開始したとします。その後、たとえばユーザーがプレーヤーを操作したい場合や再生中の曲に関する情報を入手したい場合には、アクティビティから {@code bindService()} を呼び出してサービスとの接続を確立できます。このような場合、最後のバインドが閉じられるまでは、{@code stopService()} を呼び出してもサービスは停止しません。 79510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 79610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 79710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 79810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyアクティビティと同様、サービスにもライフサイクル メソッドがあり、これらを実装することでサービスの状態の変化を監視できます。ただし、protected ではなく public で、以下の 3 つしかありません: 79910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 80010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 80110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p style="margin-left: 2em">{@code void onCreate()} <br/>{@code void onStart(Intent <i>intent</i>)} <br/>{@code void onDestroy()}</p> 80210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 80310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 80410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこれらのメソッドを実装することで、ネストされた 2 つのループからなるサービスのライフサイクルを監視できます: 80510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 80610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 80710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 80810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>サービスの<b>ライフタイム全体</b>は、<code>{@link android.app.Service#onCreate onCreate()}</code> が呼び出されたときに始まり、<code>{@link android.app.Service#onDestroy}</code> 終了したときに終わります。アクティビティと同じく、サービスも {@code onCreate()} で初期設定を行い、{@code onDestroy()} で残っていたリソースをすべて解放します。たとえば、音楽再生サービスであれば、{@code onCreate()} で音楽を再生するスレッドを作成し、{@code onDestroy()} でそのスレッドを停止できます。</li> 80910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 81010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>サービスの<b>アクティブ ライフタイム</b>は、<code>{@link android.app.Service#onStart onStart()}</code> を呼び出したときに始まります。このメソッドには、{@code startService()} に渡された Intent オブジェクトが渡されます。音楽再生サービスは、この Intent オブジェクトをみて曲を見つけ、その再生を開始します。</p> 81110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 81210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 81310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyサービスの停止に相当するコールバック、つまり {@code onStop()} メソッドはありません。 81410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p></li> 81510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 81610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 81710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 81810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty{@code onCreate()} および {@code onDestroy()} メソッドは、サービスを <code>{@link android.content.Context#startService Context.startService()}</code> または <code>{@link android.content.Context#bindService Context.bindService()}</code> のどちらで開始したかに関係なく、すべてのサービスで呼び出されます。一方、{@code onStart()} は、サービスを {@code startService()} で開始した場合のみ呼び出されます。 81910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 82010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 82110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 82210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyサービスが他からのバインドを許可している場合は、以下のコールバック メソッドを追加で実装できます: 82310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 82410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 82510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p style="margin-left: 2em">{@code IBinder onBind(Intent <i>intent</i>)} <br/>{@code boolean onUnbind(Intent <i>intent</i>)} <br/>{@code void onRebind(Intent <i>intent</i>)}</p> 82610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 82710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 82810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<code>{@link android.app.Service#onBind onBind()}</code> コールバックには {@code bindService()} に渡された Intent オブジェクトが渡され、<code>{@link android.app.Service#onUnbind onUnbind()}</code> には {@code unbindService()} 渡された Intent オブジェクトが渡されます。サービスがバインドを許可している場合は、クライアントがサービスと対話する通信チャネルを {@code onBind()} で返します。{@code onUnbind()} メソッドは、サービスに新しいクライアントが接続した場合に <code>{@link android.app.Service#onRebind onRebind()}</code> の呼び出しを要求できます。 82910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 83010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 83110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 83210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty次の図に、サービスのコールバック メソッドを示します。なお、{@code startService()} で作成されたサービスと、{@code bindService()} で作成されたサービスを分けて記述していますが、作成された方法に関係なく,すべてのサービスはクライアントからのバインドを許可できます。したがって、どのサービスも {@code onBind()} および{@code onUnbind()} メソッドの呼び出しを受け取る可能性はあります。 83310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 83410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 83510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p style="margin-left: 2em"><img src="{@docRoot}images/service_lifecycle.png" 83610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyalt="サービス コールバックの状態遷移図" /></p> 83710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 83810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 83910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="broadlife">ブロードキャスト レシーバのライフサイクル</h3> 84010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 84110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 84210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyブロードキャスト レシーバのコールバック メソッドは次の 1 つのみです: 84310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 84410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 84510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p style="margin-left: 2em">{@code void onReceive(Context <i>curContext</i>, Intent <i>broadcastMsg</i>)}</p> 84610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 84710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 84810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyレシーバにブロードキャスト メッセージが届くと、<code>{@link android.content.BroadcastReceiver#onReceive onReceive()}</code> メソッドが呼び出され、メッセージを保持する Intent オブジェクトが渡されます。ブロードキャスト レシーバは、このメソッドの実行中のみアクティブと見なされます。{@code onReceive()} 終了すると、ブロードキャスト レシーバはアクティブでなくなります。 84910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 85010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 85110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 85210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyブロードキャスト レシーバがアクティブになっているプロセスは、強制終了しないよう保護されます。一方、アクティブでないコンポーネントのみからなるプロセスは、それが消費しているメモリが他のプロセスで必要になった場合は、いつでも強制終了される可能性があります。 85310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 85410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 85510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 85610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyこの点は、ブロードキャスト メッセージへの応答に時間がかかるため、ユーザー インターフェースの他のコンポーネントを実行しているメイン スレッドとは別のスレッドで何らかの処理を行う必要がある場合に問題になります。{@code onReceive()} が新しいスレッドを生成して終了した場合、プロセス内に他にアクティブなアプリケーション コンポーネントがなければ、そのスレッドを含めたプロセス全体がアクティブでないと判断されて強制終了させられるおそれがあります。この問題を回避するには、{@code onReceive()} でサービスを開始し、そのサービスにジョブを実行させます。これにより、プロセス内にまだアクティブなコンポーネントがあると見なされます。 85710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 85810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 85910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 86010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty次のセクションでは、プロセスが強制終了される可能性が高くなる状況についてさらに詳しく説明します。 86110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 86210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 86310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 86410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<h3 id="proclife">プロセスとライフサイクル</h3> 86510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 86610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p>Android は、プロセスをできるだけ長い間維持しようとします。しかし、最終的にメモリが不足したときには、古いプロセスを削除しなければならなくなります。Android では、どのプロセスを維持し、どのプロセスを強制終了させるかを判断するため、プロセス内で実行されているコンポーネントと各コンポーネントの状態に基づいて、各プロセスを「重要度の階層」の位置づけます。まず最も重要度の低いプロセスが削除され、次は 2 番目に重要度の低いプロセス、その次に 3 番目、というように判断されます。階層は 5 つのレベルで構成されます。以下では、重要度の高いものから順に説明します: 86710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 86810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 86910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ol> 87010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 87110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><b>フォアグラウンド プロセス</b>は、ユーザーがその時点で行っている作業に必要なプロセスです。以下のいずれかの条件を満たしているプロセスは、フォアグラウンド プロセスと見なされます: 87210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 87310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 87410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>ユーザーと対話中のアクティビティを実行している(Activity オブジェクトの <code>{@link android.app.Activity#onResume 87510550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyonResume()}</code> メソッドが呼び出されている)。</li> 87610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 87710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>ユーザーと対話中のアクティビティにバインドされているサービスを実行している。</p></li> 87810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 87910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>いずれかのライフサイクル コールバック(<code>{@link android.app.Service#onCreate 88010550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyonCreate()}</code>、<code>{@link android.app.Service#onStart onStart()}</code>、または <code>{@link android.app.Service#onDestroy onDestroy()}</code>)を実行している {@link android.app.Service} オブジェクトを保持している。</p></li> 88110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 88210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p><code>{@link android.content.BroadcastReceiver#onReceive 88310550e5bd8d1725fa0ed5c553b6019c02580877fDirk DoughertyonReceive()}</code> メソッドを実行している {@link android.content.BroadcastReceiver} オブジェクトを保持している。</p></li> 88410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 88510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 88610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 88710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty同時に存在するフォアグラウンド プロセスは少数に限られています。フォアグラウンド プロセスは、メモリが極端に不足し、すべてのフォアグラウンド プロセスの実行を継続できない場合の最終手段として強制終了させられます。通常、その時点でデバイスはメモリ ページングの状態に達しており、ユーザー インターフェースを応答可能な状態に維持するためには、フォアグラウンド プロセスの一部を強制終了させなければならない状況に陥っています。 88810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p></li> 88910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 89010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p><b>可視プロセス</b>は、フォアグラウンド コンポーネントではないものの、ユーザーが見ている画面に影響を及ぼすことのできるプロセスです。以下のいずれかの条件を満たしているプロセスは、可視プロセスと見なされます:</p> 89110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 89210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<ul> 89310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li>フォアグラウンドではないがユーザーから見ることができるアクティビティを実行している(その <code>{@link android.app.Activity#onPause onPause()}</code> メソッドが呼び出されている)。これは、たとえばフォアグラウンド アクティビティがダイアログで、その背後に直前のアクティビティが見えるような状況です。</li> 89410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 89510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p>ユーザーから見ることのできるアクティビティにバインドされているサービスを実行している。</p></li> 89610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ul> 89710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 89810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 89910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty可視プロセスは、非常に重要なプロセスと見なされ、すべてのフォアグラウンド プロセスの実行を維持するために必要でない限り、強制終了させられることはありません。 90010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p></li> 90110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 90210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p><b>サービス プロセス</b>は、<code>{@link android.content.Context#startService startService()}</code> メソッドで開始されたサービスを実行しているプロセスのうち、より重要度の高い 2 つのレベルのどちらにも該当しないプロセスです。サービス プロセスは、ユーザーに見えるものとの直接的な関係はありませんが、たとえばバックグラウンドでの MP3 の再生、ネットワークからのデータのダウンロードなど、ユーザーが気にかけている処理であることが一般的です。したがって、すべてのフォアグラウンド プロセスと可視プロセスに加え、これらのサービス プロセスの実行を維持するだけのメモリが確保できる限り、強制終了させられることはありません。 90310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p></li> 90410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 90510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p><b>バックグラウンド プロセス</b>は、その時点でユーザーから見えないアクティビティを保持している(Activity オブジェクトの <code>{@link android.app.Activity#onStop onStop()}</code> メソッドが呼び出されている)プロセスです。これらのプロセスは、ユーザー エクスペリエンスに直接的には影響しておらず、フォアグラウンド、可視、サービス プロセスからメモリが要求された場合はいつでも強制終了する可能性があります。通常は数多くのバックグラウンド プロセスが実行されているため、それらを LRU(least recently used)リストに登録し、ユーザーが一番最近見たアクティビティのプロセスが最後に強制終了するような仕組みになっています。アクティビティにライフサイクル メソッドが正しく実装されており、現在の状態が正しく保存されていれば、プロセスを強制終了してもユーザー エクスペリエンスに悪影響が及ぶことはありません。 90610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p></li> 90710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 90810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<li><p><b>空のプロセス</b>は、アクティブなアプリケーション コンポーネントを保持していないプロセスです。このようなプロセスを維持しておく唯一の理由は、これをキャッシュとして使用し、次回コンポーネントを実行するときの起動時間を短くするためです。多くの場合、システムはこれらのプロセスを強制終了させて、プロセス キャッシュとその基礎となるカーネル キャッシュの間でシステム リソース全体のバランスを取ります。</p></li> 90910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 91010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</ol> 91110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 91210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 91310550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty各プロセスは、その時点でアクティブなコンポーネントの重要度に基づいて、そのプロセスが取りうる最も高いレベルにランク付けされます。たとえば、あるプロセスがサービスと可視アクティビティをホストしている場合、そのプロセスはサービス プロセスではなく可視プロセスとしてランク付けされます。 91410550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 91510550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 91610550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 91710550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyまた、あるプロセスに他のプロセスが依存しているために、そのプロセスのランクが引き上げられる可能性もあります。他のプロセスから依存されているプロセスが、依存しているプロセスよりも低いレベルにランク付けされることはありません。たとえば、プロセス A 内のコンテンツ プロバイダにプロセス B 内のクライアントが依存している場合や、プロセス A 内のサービスがプロセス B 内のコンポーネントにバインドされている場合、プロセス A は常にプロセス B よりは重要度が高いと見なされます。 91810550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 91910550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty 92010550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty<p> 92110550e5bd8d1725fa0ed5c553b6019c02580877fDirk Doughertyサービスを実行しているプロセスは、バックグラウンド アクティビティを実行しているプロセスよりも高くランク付けされます。したがって、時間のかかる処理を実行する場合、特にその処理がアクティビティよりも長く続くような場合は、単にスレッドを生成するのではなく、その処理用のサービスを開始することをおすすめします。たとえば、バックグラウンドで音楽を再生する場合や、カメラで撮影した写真を Web サイトにアップロードする場合などはこれに当たります。サービスを使用することで、アクティビティがどのような状況にあっても、処理の重要度として「サービス プロセス」レベル以上を維持できます。<a href="#broadlife">ブロードキャスト レシーバのライフサイクル</a>のセクションでも説明しましたが、ブロードキャスト レシーバにおいてもこれと同じ理由で、処理に時間がかかる場合はスレッドではなくサービスを使用することをおすすめします。 92210550e5bd8d1725fa0ed5c553b6019c02580877fDirk Dougherty</p> 923