1page.title=プロセスとスレッド 2page.tags=lifecycle,background 3 4@jd:body 5 6<div id="qv-wrapper"> 7<div id="qv"> 8 9<h2>本書の内容</h2> 10<ol> 11<li><a href="#Processes">プロセス</a> 12 <ol> 13 <li><a href="#Lifecycle">プロセスのライフサイクル</a></li> 14 </ol> 15</li> 16<li><a href="#Threads">スレッド</a> 17 <ol> 18 <li><a href="#WorkerThreads">ワーカー スレッド</a></li> 19 <li><a href="#ThreadSafe">スレッド セーフのメソッド</a></li> 20 </ol> 21</li> 22<li><a href="#IPC">プロセス間通信(IPC)</a></li> 23</ol> 24 25</div> 26</div> 27 28<p>アプリケーション コンポーネントが開始し、アプリケーションに他に実行中のコンポーネントがない場合、Android システムは実行用のシングル スレッドを持つアプリケーション用の新しい Linux プロセスを開始します。 29 30デフォルトでは、同じアプリケーションのすべてのコンポーネントは同じプロセスとスレッド(「メイン」 スレッドと呼ばれます)で実行します。 31アプリケーション コンポーネントが開始したときに、既にそのアプリケーションのプロセスが存在する場合(アプリケーションからの他のコンポーネントが存在するため)、コンポーネントはそのプロセス内で開始し、同じ実行用のスレッドを使用します。 32 33ただし、アプリケーション内の別のコンポーネントを別のプロセスで実行するよう調整でき、あらゆるプロセスに対して追加のスレッドを作成できます。 34 35</p> 36 37<p>このドキュメントでは、Android アプリケーションでプロセスとスレッドがどのように動作するかについて説明します。</p> 38 39 40<h2 id="Processes">プロセス</h2> 41 42<p>デフォルトでは、同じアプリケーションのすべてのコンポーネントは同じプロセスで実行し、ほとんどのアプリケーションでこの動作を変更する必要はありません。 43ただし、特定のコンポーネントが属するプロセスを管理する必要がある場合は、マニフェスト ファイルでそれを行うことができます。 44</p> 45 46<p>コンポーネント要素の各タイプのマニフェスト エントリ(<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code 47<activity>}</a>、<a href="{@docRoot}guide/topics/manifest/service-element.html">{@code 48<service>}</a>、<a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code 49<receiver>}</a>、<a href="{@docRoot}guide/topics/manifest/provider-element.html">{@code 50<provider>}</a>)は、コンポーネントを実行するプロセスを指定できる {@code android:process} 属性をサポートしています。— 51—この属性を設定して、各コンポーネントが独自のプロセスで実行するようにしたり、一部のコンポーネントで同じプロセスを共有し、残りのコンポーネントでは別のプロセスを使用するようにしたりできます。 52また、{@code android:process} を設定すると、異なるアプリケーションのコンポーネントを同じプロセスで実行させることもできます。この場合、アプリケーションが同じ Linux ユーザー ID を共有していて、同じ証明書で署名されている必要があります。 53— 54 55</p> 56 57<p><a href="{@docRoot}guide/topics/manifest/application-element.html">{@code 58<application>}</a> 要素も {@code android:process} 属性をサポートしており、すべてのコンポーネントに適用されるデフォルトの値を設定します。 59</p> 60 61<p>メモリの空きが少なくなり、早急にユーザーに提供する必要のあるプロセスが必要とする場合は、Android がプロセスをどこかの時点でシャットダウンするよう決定する場合があります。 62破棄されたプロセスで実行しているアプリケーション コンポーネントは、結果的に破棄されます。 63プロセスは、それらのコンポーネントの処理が再度発生したときに再開されます。 64</p> 65 66<p>破棄するプロセスを決定する際、Android システムはユーザーへの相対的な重要度を測ります。 67たとえば、画面に見えているアクティビティをホストするプロセスよりも、もう画面に見えていないアクティビティをホストするプロセスの方が先にシャットダウンされることになります。 68そのため、プロセスを停止するかどうかは、そのプロセスで実行しているコンポーネントの状態によって決まります。 69ここから、停止するプロセスを決定する規則について詳しく説明していきます。 70 </p> 71 72 73<h3 id="Lifecycle">プロセスのライフサイクル</h3> 74 75<p>Android システムは、可能な限り長期間アプリケーション プロセスを維持しようとしますが、新たに重要なプロセスが発生した際には、メモリを回収するために古いプロセスをいずれは削除する必要が生じます。 76どのプロセスを維持して、どのプロセスを強制終了するかを決定するため、システムはプロセスで実行しているコンポーネントとコンポーネントの状態に基づいて、各プロセスを「重要度の階層」に位置付けします。 77 78 79まず、重要度の最も低いプロセスが除去され、その後システム リソースを回復できるまで重要度の低い順に除去していきます。 80 81</p> 82 83<p>重要度の階層には 5 つのレベルがあります。次の一覧では、さまざまなプロセスのタイプを重要度の高い順に表しています(1 つ目のプロセスが<em>最も重要度が高く</em>、<em>最後に強制終了</em>されます)。 84 85</p> 86 87<ol> 88 <li><b>フォアグラウンド プロセス</b> 89 <p>ユーザーが現在行っている操作に必要なプロセスです。次の条件のいずれかにあてはまる場合、そのプロセスはフォアグラウンドにあるとみなされます。 90</p> 91 92 <ul> 93 <li>ユーザーが操作している {@link android.app.Activity} のホストになっている({@link 94android.app.Activity} の{@link android.app.Activity#onResume onResume()} メソッドが呼び出された)。 95</li> 96 97 <li>ユーザーが操作しているアクティビティにバインドされている {@link android.app.Service} のホストになっている。 98</li> 99 100 <li>「フォアグラウンド」 で実行中の {@link android.app.Service} のホストになっている(サービスが {@link android.app.Service#startForeground startForeground()} を呼び出した)。— 101 102 103 <li>{@link android.app.Service#onCreate onCreate()}、{@link android.app.Service#onStart 104onStart()}、{@link android.app.Service#onDestroy onDestroy()} のいずれかのライフサイクル コールバックを実行している {@link android.app.Service} のホストになっている。 105</li> 106 107 <li>{@link 108 android.content.BroadcastReceiver#onReceive onReceive()} メソッドを実行している {@link android.content.BroadcastReceiver} のホストになっている。</li> 109 </ul> 110 111 <p>通常は、2~3 個のフォアグラウンド プロセスが存在します。フォアグラウンド プロセスは、それらすべてを実行できなくなるほどメモリが少なくなると、最終手段として強制終了されます。 112—通常はその時点で、端末がメモリのページング状態に達しているため、ユーザー インターフェースのレスポンシブを維持するには一部のフォアグラウンド プロセスを強制終了する必要があります。 113 114</p></li> 115 116 <li><b>可視プロセス</b> 117 <p>フォアグラウンド コンポーネントはないものの、ユーザーに対して画面上に表示される内容に影響を与える可能性のあるプロセスです。 118次の条件のいずれかにあてはまる場合、そのプロセスは可視プロセスであるとみなされます。 119</p> 120 121 <ul> 122 <li>フォアグラウンドにないが、ユーザーに表示されている {@link android.app.Activity} のホストになっている({@link android.app.Activity#onPause onPause()} メソッドが呼び出された)。 123たとえば、フォアグラウンドのアクティビティがダイアログを開始したときに、前のアクティビティがその背後に見えている場合などがあります。 124 125</li> 126 127 <li>可視(またはフォアグラウンドの)アクティビティにバインドされている {@link android.app.Service} のホストになっている。 128</li> 129 </ul> 130 131 <p>可視プロセスは非常に重要度が高いため、フォアグラウンド プロセスの実行を維持するのに必要な場合のみ、強制終了されます。 132 </p> 133 </li> 134 135 <li><b>サービス プロセス</b> 136 <p>{@link 137android.content.Context#startService startService()} メソッドで開始されたサービスを実行するプロセスで、上の 2 つのカテゴリに分類されないものです。 138サービス プロセスは、ユーザーに表示される内容には直接関係ありませんが、ユーザーにとって必要な操作を実行している場合が多いため(バックグラウンドで音楽を再生したり、ネットワーク経由でデータをダウンロードしたりなど)、フォアグラウンド プロセスと可視プロセスのすべてと合わせて、それらを継続するのにメモリが不足した場合のみ強制終了されます。 139 140 141 </p> 142 </li> 143 144 <li><b>バックグラウンド プロセス</b> 145 <p>現在ユーザーに表示されていないアクティビティを有するプロセスです(アクティビティの {@link android.app.Activity#onStop onStop()} メソッドが呼び出された)。 146ユーザーの操作性に直接影響を与えるものではなく、フォアグラウンド プロセス、可視プロセス、サービス プロセス用にメモリを回収する必要があればいつでも強制終了されます。 147 148 149通常はバックグラウンドで実行するプロセスは多数あるため、最近ユーザーに表示されたアクティビティのあるプロセスを最後に強制終了するよう、LRU(最小使用頻度)リストに入れられます。 150 151アクティビティがライフサイクル メソッドを正確に実装し、現在の状態を保存する場合は、そのプロセスを強制終了しても、ユーザーがそのアクティビティに戻ったときに、アクティビティがすべての視覚的状態を復元するため、ユーザーの操作性に視覚的な影響はありません 152 153 154。状態の保存と復元の詳細については、「<a href="{@docRoot}guide/components/activities.html#SavingActivityState">Activities</a>」のドキュメントをご覧ください。 155</p> 156 </li> 157 158 <li><b>空のプロセス</b> 159 <p>アクティブなアプリケーション コンポーネントが 1 つも含まれていないプロセスです。このようなプロセスは、プロセスをキャッシュしておくことのみを目的として保持され、次回コンポーネントを実行する際の起動時間を向上させることができます。 160 161システムは、プロセスのキャッシュと下層のカーネル キャッシュとの間の全体的なシステム リソースのバランスを整える目的でこれらのシステムを頻繁に強制終了します。 162</p> 163 </li> 164</ol> 165 166 167 <p>Android では、プロセスで現在アクティブなコンポーネントの重要度に基づいて、あてはまるランクのなかで最も高いランクにプロセスを位置付けます。 168たとえば、サービス アクティビティと可視アクティビティの両方のホストとなっているプロセスは、サービス プロセスではなく、可視プロセスとして位置付けられます。 169</p> 170 171 <p>さらに、他のプロセスから依存されているプロセスの位置付けが上がる場合があります。他のプロセスのために動作しているプロセスは、その対象プロセスよりも下に位置付けられることはありません。 172— 173たとえば、プロセス A のコンテンツ プロバイダが、プロセス B のクライアントのために動作している場合や、プロセス A のサービスがプロセス B のコンポーネントにバインドされている場合、プロセス A の重要度は常にプロセス B 以上であるとみなされます。 174 175</p> 176 177 <p>サービスを実行するプロセスは、バックグラウンドのアクティビティを持つプロセスよりも上に位置付けされるため、長時間の操作を開始するアクティビティでは、特に、操作がアクティビティよりも長く続く場合、ワーカー スレッドを作成するよりもその操作の<a href="{@docRoot}guide/components/services.html">サービス</a>を開始する方がよいと考えられます。たとえば、ウェブサイトに写真をアップロードするアクティビティでは、ユーザーがアクティビティから離れた後もアップロードをバックグラウンドで続行できるよう、アップロードを実行するサービスを開始することをお勧めします。サービスを使用することで、アクティビティの状況に変わらず、その操作に「サービス プロセス」以上の優先度が保証されることになります。 178 179 180 181 182 183同じ理由から、ブロードキャスト レシーバーでもスレッドに長時間の処理を置くのではなく、サービスを採用するようお勧めします。 184</p> 185 186 187 188 189<h2 id="Threads">スレッド</h2> 190 191<p>アプリケーション起動の際、システムは アプリケーション実行用のスレッドを作成します。これは、「メイン スレッド」と呼ばれます。 192このスレッドは、イベント(描画イベントを含む)を適切なユーザー インターフェース ウィジェットに送信する役割を担うため非常に重要です。 193また、これはアプリケーションが Android UI ツールキット({@link 194android.widget} と {@link android.view} パッケージからのコンポーネント)からのコンポーネントとやり取りをするスレッドでもあります。 195そのため、メイン スレッドは UI スレッドと呼ばれることもあります。 196</p> 197 198<p>コンポーネントのインスタンスごとに別のスレッドが作成されることは<em>ありません</em>。同じプロセスで実行するすべてのコンポーネントは UI スレッドでインスタンス化され、スレッドから送られた各コンポーネントをシステムが呼び出します。 199 200結果的に、システムのコールバック(ユーザー操作を報告する {@link android.view.View#onKeyDown onKeyDown()} やライフサイクル コールバック メソッドなど)に応答するメソッドは常にプロセスの UI スレッドで実行することになります。 201 202</p> 203 204<p>たとえば、ユーザーが画面上のボタンをタッチすると、アプリの UI スレッドがタッチ イベントをウィジェットに送信し、ウィジェットがそのタッチされた状態を設定してイベント キューに無効化の要求を投稿します。 205 206UI スレッドが要求をキューから取り出し、ウィジェットに自身を描画するよう通知します。 207</p> 208 209<p>アプリがユーザー操作に応答して集中的な動作を実行する場合、アプリケーションを正しく実装していない限りこのシングル スレッド モデルではパフォーマンスの低下につながる可能性があります。 210具体的には、すべてが UI スレッドで行われている場合、長ネットワークへのアクセスやデータベースへの問い合わせといった時間のかかる操作を実行すると UI 全体をブロックしてしまいます。スレッドがブロックされると、描画イベントを含むすべてのイベントを送信できなくなります。 211 212 213ユーザー側には、アプリケーションがハングしたように見えます。 214さらには、UI スレッドが数秒以上(現時点では 5 秒以上)ブロックされると、ユーザーに<a href="http://developer.android.com/guide/practices/responsiveness.html">「アプリケーションが応答していません」</a>のダイアログが表示されます。 215 216ユーザーはアプリケーションを停止するか、不快な場合はアンインストールしてしまう可能性があります。 217</p> 218 219<p>また、Android UI ツールキットはスレッド セーフ<em>ではありません</em>。そのため、ワーカー スレッドから UI を操作できません。すべての操作は、UI スレッドから行う必要があります。 220— 221そのため、Android のシングル スレッド モデルには 2 つの明快なルールがあります。</p> 222 223<ol> 224<li>UI スレッドをブロックしない 225<li>UI スレッド以外から Android UI ツールキットにアクセスしない 226</ol> 227 228<h3 id="WorkerThreads">ワーカー スレッド</h3> 229 230<p>上記で説明したシングル スレッド モデルにより、アプリケーションの UI の応答性のためにも UI スレッドをブロックしないことが不可欠です。 231即座に実行する必要のない操作の場合は、別のスレッド(「バックグラウンド」スレッドや「ワーカー」スレッド)で実行するようにする必要があります。 232 233</p> 234 235<p>例として、別のスレッドから画像をダウンロードして {@link android.widget.ImageView} に表示するクリック リスナのコードの一部を次に示します。 236</p> 237 238<pre> 239public void onClick(View v) { 240 new Thread(new Runnable() { 241 public void run() { 242 Bitmap b = loadImageFromNetwork("http://example.com/image.png"); 243 mImageView.setImageBitmap(b); 244 } 245 }).start(); 246} 247</pre> 248 249<p>ここでは、ネットワークの操作を処理する新しいスレッドを作成しているため、一見問題ないように見えます。 250ただし、これは<em>UI スレッド以外から Android UI ツールキットにアクセスしない</em>というシングルスレッド モデルの 2 つ目のルールに違反しています。このサンプルは、UI スレッドではなくワーカー スレッドから {@link 251android.widget.ImageView} を変更しています。— 252結果として、未定義かつ予想外の動作を引き起こし、追跡が難しく時間のかかる作業になってしまいます。 253</p> 254 255<p>この問題を修正するため、Android には UI スレッド以外からのアクセス方法がいくつか用意されています。 256使用できるメソッドは次のとおりです。</p> 257 258<ul> 259<li>{@link android.app.Activity#runOnUiThread(java.lang.Runnable) 260Activity.runOnUiThread(Runnable)}</li> 261<li>{@link android.view.View#post(java.lang.Runnable) View.post(Runnable)}</li> 262<li>{@link android.view.View#postDelayed(java.lang.Runnable, long) View.postDelayed(Runnable, 263long)}</li> 264</ul> 265 266<p>たとえば、上記のコードは {@link 267android.view.View#post(java.lang.Runnable) View.post(Runnable)} メソッドを使用して修正できます。</p> 268 269<pre> 270public void onClick(View v) { 271 new Thread(new Runnable() { 272 public void run() { 273 final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png"); 274 mImageView.post(new Runnable() { 275 public void run() { 276 mImageView.setImageBitmap(bitmap); 277 } 278 }); 279 } 280 }).start(); 281} 282</pre> 283 284<p>これで、この実装がスレッドセーフになりました。ネットワーク操作は別のスレッドから実行され、{@link android.widget.ImageView} は UI スレッドから操作されます。 285</p> 286 287<p>ただし、操作が複雑になるにつれて、この種のコードも複雑化してメンテナンスも難しくなります。 288ワーカー スレッドとのより複雑なやり取りを処理するため、ワーカー スレッドで {@link android.os.Handler} を使うと、UI スレッドから配信されたメッセージを処理できます。 289 290ただし、最善なのは{@link android.os.AsyncTask} クラスを拡張することであり、これにより UI を操作する必要のあるワーカー スレッドのタスクの実行を簡素化できます。 291</p> 292 293 294<h4 id="AsyncTask">AsyncTask を使用する</h4> 295 296<p>{@link android.os.AsyncTask} では、ユーザー インターフェースに非同期の処理を実行できます。 297スレッドやハンドラを自身で処理する必要なく、ワーカー スレッドの操作をブロックし、結果を UI スレッドに発行します。 298</p> 299 300<p>これを使用するには、{@link android.os.AsyncTask} をサブクラス化し、バックグラウンド スレッドのプール内で実行する {@link 301android.os.AsyncTask#doInBackground doInBackground()} コールバック メソッドを実装する必要があります。 302UI を更新するには、{@link 303android.os.AsyncTask#onPostExecute onPostExecute()} を実装します。これは {@link 304android.os.AsyncTask#doInBackground doInBackground()} からの結果を配信し、UI スレッド内で実行されるため、UI を安全に更新できます。その後、UI スレッドから {@link android.os.AsyncTask#execute execute()} を呼び出してタスクを実行できます。 305 306</p> 307 308<p>たとえば、次のように {@link android.os.AsyncTask} を使って前出の例を実装できます。 309</p> 310 311<pre> 312public void onClick(View v) { 313 new DownloadImageTask().execute("http://example.com/image.png"); 314} 315 316private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { 317 /** The system calls this to perform work in a worker thread and 318 * delivers it the parameters given to AsyncTask.execute() */ 319 protected Bitmap doInBackground(String... urls) { 320 return loadImageFromNetwork(urls[0]); 321 } 322 323 /** The system calls this to perform work in the UI thread and delivers 324 * the result from doInBackground() */ 325 protected void onPostExecute(Bitmap result) { 326 mImageView.setImageBitmap(result); 327 } 328} 329</pre> 330 331<p>ワーカー スレッドで処理される作業と、UI スレッドで処理される作業が分けられたため、UI は安全に、コードはシンプルになりました。 332</p> 333 334<p>このクラスの使用方法をより深く理解するには {@link android.os.AsyncTask} に目を通す必要がありますが、ここに、その仕組みについて簡単に挙げておきます。 335</p> 336 337<ul> 338<li>ジェネリックを使ってパラメータのタイプ、進捗の値、タスクの最終値を指定できます 339</li> 340<li>{@link android.os.AsyncTask#doInBackground doInBackground()} メソッドがワーカー スレッド上で自動的に実行されます 341</li> 342<li>{@link android.os.AsyncTask#onPreExecute onPreExecute()}、{@link 343android.os.AsyncTask#onPostExecute onPostExecute()}、{@link 344android.os.AsyncTask#onProgressUpdate onProgressUpdate()}はすべて UI スレッドで呼び出されます</li> 345<li>{@link android.os.AsyncTask#doInBackground doInBackground()} から返される値は、{@link android.os.AsyncTask#onPostExecute onPostExecute()} に送られます 346</li> 347<li>{@link android.os.AsyncTask#publishProgress publishProgress()} は、{@link 348android.os.AsyncTask#doInBackground doInBackground()} でいつでも呼び出すことができます。UI スレッドで {@link 349android.os.AsyncTask#onProgressUpdate onProgressUpdate()} を実行できます</li> 350<li>いつでも、どのスレッドからでもタスクをキャンセルできます</li> 351</ul> 352 353<p class="caution"><strong>警告:</strong> ワーカー スレッドの使用時に発生する可能性のあるもう 1 つの問題として、<a href="{@docRoot}guide/topics/resources/runtime-changes.html">実行時の設定が変更</a>された(ユーザーが画面の向きを変えた場合など)ことによってアクティビティが予期せず再起動され、ワーカー スレッドが破棄されてしまうことがあります。 354 355このような再起動の間タスクを維持する方法、アクティビティが破棄されたときの正しいタスクのキャンセル方法については、<a href="http://code.google.com/p/shelves/">Shelves</a> のサンプル アプリケーションのソース コードをご覧ください。 356 357</p> 358 359 360<h3 id="ThreadSafe">スレッド セーフのメソッド</h3> 361 362<p> 状況によっては、実装したメソッドが複数のスレッドから呼び出されることがあり、その場合はメソッドがスレッドセーフになるよう作成する必要があります。 363 </p> 364 365<p>主に、<a href="{@docRoot}guide/components/bound-services.html">バインドされたサービス</a>のメソッドなど、リモートで呼び出されるメソッドなどがこれに該当します。—{@link android.os.IBinder} に実装されたメソッドへの呼び出しが、{@link android.os.IBinder IBinder} を実行しているプロセスと同じプロセスで発生した場合、メソッドは呼び出し側のスレッドで実行されます。ただし、呼び出しが別のプロセスで起こった場合は、メソッドはシステムが {@link android.os.IBinder 366IBinder} と同じプロセスに保持するスレッドのプールから選ばれたスレッドで実行されます(プロセスの UI スレッドでは実行されません)。 367 368 369 370たとえば、サービスの {@link android.app.Service#onBind onBind()} メソッドがサービスのプロセスの UI スレッドから呼び出されるのに対して、{@link android.app.Service#onBind 371onBind()} が返すオブジェクトで実装されたメソッド(RPC メソッドを実装するサブクラスなど)は、プール内のスレッドから呼び出されます。 372 373 374サービスは複数のクライアントを持てるため、複数のプール スレッドが同じ {@link android.os.IBinder IBinder} メソッドを同時に動かすことができます。このため、{@link android.os.IBinder 375IBinder} メソッドはスレッドセーフになるよう実装する必要があります。 376</p> 377 378<p> 同様に、コンテンツ プロバイダは他のプロセスから送られたデータ要求を受け取ることができます。{@link android.content.ContentResolver} クラスと {@link android.content.ContentProvider} クラスによってプロセス間通信がどのように管理されているかが見えなくなりますが、それらの要求に応答する {@link 379android.content.ContentProvider} メソッド({@link 380android.content.ContentProvider#query query()}、 {@link android.content.ContentProvider#insert 381insert()}、{@link android.content.ContentProvider#delete delete()}、{@link 382android.content.ContentProvider#update update()}、{@link android.content.ContentProvider#getType 383getType()})は、プロセスの UI スレッドではなく、コンテンツ プロバイダのプロセスにあるスレッドのプールから呼び出されます。 384 385 386——これらのメソッドは同時に複数のスレッドから呼び出される可能性があるため、先ほどと同様にスレッドセーフになるよう実装する必要があります。 387 </p> 388 389 390<h2 id="IPC">プロセス間通信(IPC)</h2> 391 392<p>Android では、リモート プロシージャ コール(RPC)を使ったプロセス間通信のメカニズムを備えており、メソッドはアクティビティや他のアプリケーション コンポーネントから呼び出された後に、リモート(別のプロセス)で実行され、結果を呼び出し側に返します。 393 394 395これにより、メソッドの呼び出しとそのデータをオペレーティング システムが理解できるレベルまで分解し、ローカル プロセスとアドレス空間からリモート プロセスとアドレス空間にそれを送信して、そこで呼び出しが再度組み立てて、再現します。 396 397その後、戻り値が逆方向に伝達されます。 398Android ではこれらの IPC トランザクションを実行するためのすべてのコードが用意されているため、開発者は RPC のプログラミング インターフェースの定義と実装に集中できます。 399 </p> 400 401<p>IPC を実行するには、アプリケーションが {@link 402android.content.Context#bindService bindService()} を使ってサービスにバインドされている必要があります。詳細については、デベロッパー ガイドの「<a href="{@docRoot}guide/components/services.html">サービス</a>」をご覧ください。</p> 403 404 405<!-- 406<h2>Beginner's Path</h2> 407 408<p>For information about how to perform work in the background for an indefinite period of time 409(without a user interface), continue with the <b><a 410href="{@docRoot}guide/components/services.html">Services</a></b> document.</p> 411--> 412