Android のサービスの包括的な概要
1. サービスの種類
-
【運用場所による分類:ローカルサービスとリモートサービスに分かれます】
-
ローカル サービス (ローカル): このサービスはメイン プロセスにアタッチされます。
-
利点:
サービスは独立したプロセスではなくメイン プロセスにアタッチされるため、リソースがある程度節約されます。また、ローカル サービスは同じプロセス内にあるため、IPC や AIDL を必要としません。対応するbindServiceはさらに便利になります。 -
欠点: メインプロセスが強制終了されると、サービスは終了します。
-
アプリケーション シナリオ: HTC の音楽再生サービス、Tiantiandongting 音楽再生サービスなどの非常に一般的なアプリケーション。
-
-
リモート サービス (リモート): このサービスは独立したプロセスです。
-
利点:
サービスは独立したプロセスであり、対応するプロセス名の形式は、パッケージ名に指定した android:process 文字列を加えたものです。独立したプロセスであるため、
Activity が存在するプロセスが終了してもサービスは実行され続け、他のプロセスの影響を受けることがないため、複数のプロセスに対して柔軟性の高いサービスを提供できます。 -
短所:
このサービスは独立したプロセスであるため、特定のリソースを占有し、IPC に AIDL を使用するのは少し面倒です。- アプリケーション: システム サービスを提供する一部のサービス。そのようなサービスは常駐します。
-
-
-
【動作の種類による分類:フォアグラウンドサービスとバックグラウンドサービスに分かれます】
-
受付:
-
通知欄には「ONGOING」の通知が表示されますが、サービスが終了すると通知欄の通知も消えるため、ユーザーへの一定の通知効果があります。
-
用途:音楽再生サービスなど共通。
-
-
バックグラウンド サービス:
デフォルトのサービスはバックグラウンド サービスです。つまり、ONGOING の通知は通知列に表示されません。サービスが終了すると、ユーザーはその効果を実感できなくなります。-
アプリケーション:
天気予報の更新、日付の同期、電子メールの同期など、プロンプトを実行または終了する必要のない特定のサービス。 -
バックグラウンド サービス ONGOING (中断されない) 通知を作成して、フォアグラウンド サービスにすることができますか?
- 答えは「いいえ」です。フォアグラウンド サービスは、上記の作業を行った後、startForeground (Android 2.0 以降のバージョン) または setForeground (Android 2.0 以降のバージョン) を呼び出して、サービスをフォアグラウンド サービスにする必要があります。この利点は、サービスが外部で終了された場合でも、ONGOING 通知が削除されることです。
-
-
-
【用途別分類】:
-
startService によって開始されるサービスは、
主に通信なしでバックグラウンド タスクを実行するサービスを開始するために使用されます。サービスを停止するには、stopService を使用します -
bindService によって開始されるサービス
このメソッドによって開始されるサービスは通信する必要があります。サービスを停止するには、unbindService を使用します。 -
startService は、bindService によって開始されたサービスでもあり、
サービスを停止するには、stepService と unbindService を同時に使用する必要があります。
[上記 3 つの方法で開始されたサービスのライフサイクルも異なります]。
-
2. 【サービスとスレッドの違い】
-
スレッド: スレッドはプログラム実行の最小単位であり、CPU を割り当てるための基本単位です。スレッドを使用して、いくつかの非同期操作を実行できます。
-
Service: Service は Android の仕組みであり、実行中、Local Service であれば、対応する Service がメインプロセスのメインスレッド上で実行されます。例: onCreate、onStart これらの関数はすべて、システムによって呼び出されるときにメイン プロセスのメイン スレッドで実行されます。リモート サービスの場合、対応するサービスは独立したプロセスのメイン スレッドで実行されます。したがって、サービスをスレッドとして理解しないでください。スレッドとは何の関係もありません。
-
この場合、なぜ Service を使用するのでしょうか?
実はこれは Android のシステムの仕組みに関係しているのですが、Thread を例に挙げてみましょう。Thread の操作は、Activity とは独立しています。つまり、Activity が終了した後、Thread を積極的に停止しないか、Thread 内の run メソッドが実行されない場合、Thread は実行を継続します。ここで問題が発生します。アクティビティが終了すると、スレッドへの参照を保持できなくなります。一方、異なるアクティビティで同じスレッドを制御する方法はありません。
例: スレッドが一定の間隔で何らかの同期のためにサーバーに接続する必要がある場合、アクティビティが開始されていないときでもスレッドが実行されている必要があります。現時点では、アクティビティを開始するときに、アクティビティ内で以前に作成されたスレッドを制御する方法はありません。したがって、サービスを作成して開始し、サービス内のスレッドを作成、実行、制御する必要があります。これにより、問題は解決されます (どのアクティビティも同じサービスを制御でき、システムは対応するサービスのインスタンスのみを作成するため)。
-
したがって、Service はメッセージ サービスと考えることができ、Context を使用して任意の場所で Context.startService、Context.stopService、Context.bindService、Context.unbindService を呼び出して制御することができます。また、Service に BroadcastReceiver を登録することもできます。ブロードキャストを送信して制御することもできます。もちろん、これらは Thread では実行できません。
3. 【サービスライフサイクル】
onCreate onStart onDestroy onBind
-
開始されたサービスのライフサイクル: Context.startService メソッドを呼び出すアクティビティによってサービスが開始された場合、bindService を使用してサービスにバインドするアクティビティ、または unbindService を使用してサービスのバインドを解除するアクティビティが存在するかどうかに関係なく、サービスはバックグラウンドで実行されます。Service が startService メソッドによって複数回開始された場合、onCreate メソッドは 1 回だけ呼び出され、onStart は複数回 (startService の呼び出しの数に対応して) 呼び出され、システムは Service のインスタンスを 1 つだけ作成します (したがって、stopService 呼び出しは 1 回だけであることを知っておく必要があります)。Service は、stopService または独自の stopSelf メソッドが呼び出されるまで、対応するプログラムのアクティビティが実行されているかどうかに関係なく、常にバックグラウンドで実行されます。もちろん、システムリソースが不足した場合、Androidシステムもサービスを終了する可能性があります。
-
バインドされたサービスのライフサイクル: Context.bindService メソッドを呼び出すアクティビティによってサービスがバインドされ、開始された場合、bindService が何回呼び出されても、onCreate メソッドは 1 回だけ呼び出され、onStart メソッドは決して呼び出されません。呼ばれる。接続が確立された後、サービスは、Context.unbindService が呼び出されて切断されない限り、または前に bindingService を呼び出したコンテキストが存在しない限り (アクティビティの終了時など)、実行を続けます。システムは自動的にサービスを停止します。対応する onDestroy が呼び出されます。
-
開始およびバインドされたサービスのライフサイクル: サービスが開始されて再度バインドされた場合、サービスは常にバックグラウンドで実行されます。また、どのように呼び出されても、onCreate は 1 回だけ呼び出され、startService が呼び出された回数に応じて Service の onStart が何回呼び出されます。unbindService を呼び出してもサービスは停止しませんが、サービスを停止するにはサービスの stopService または stopSelf を呼び出す必要があります。
-
サービスが停止したときにサービスをクリアします。サービスが終了すると (1、stopService を呼び出し、2、stopSelf を呼び出し、3、バインドされた接続がなくなった (開始されていない))、onDestroy メソッドが呼び出されます。ここで、次のようにする必要があります。サービス内で作成および実行されているスレッドを停止するなど、いくつかのクリーニング作業を実行します。
注意してください:
-
ServiceにバインドするためにbindServiceを呼び出すときは、アンバインドする場所で必ずunbindServiceを呼び出す必要があることに注意してください(ただし、Activityが終了するとバインドは自動的に解放され、Serviceは自動的に停止します)。
-
startService を使用してサービスを開始した後は、bindService を使用するかどうかに関係なく、必ず stopService を使用してサービスを停止することに注意してください。
-
startServiceとbindServiceを同時に使用する場合、Serviceを終了するにはunbindServiceとstopServiceを同時に呼び出す必要があることに注意してください。startServiceとbindServiceの呼び出し順序に関係なく、unbindServiceが最初に呼び出された場合、この時点ではサービスは自動的に終了せず、その後にサービスが呼び出される stopService が停止します stopService が最初に呼び出された場合、この時点ではサービスは終了せず、その後サービスは自動的に停止しますunbindService を呼び出した後、または以前に bindingService を呼び出した Context が存在しない場合 (Activity が終了した場合など)。
-
携帯電話の画面を回転する際、携帯電話の画面が「横」と「縦」の間で変化するときに、このときにアクティビティが自動的に回転する場合、その回転は実際にはアクティビティの再作成であるため、ローテーション前にbindServiceを使用して確立された接続は切断されます(コンテキストが存在しません)。対応するサービスのライフサイクルは上記と同じです。
-
SDK 2.0 以降のバージョンでは、対応する onStart は非推奨になり、onStartCommand に変更されましたが、以前の onStart は引き続き有効です。つまり、SDK 2.0 以降を使用してアプリケーションを開発する場合は、onStart の代わりに onStartCommand を使用する必要があります。
4. AndroidManifest.xmlのService要素の共通オプション
android:name ------------- 服务类名
android:label -------------- 服务的名字,如果此项不设置,那么默认显示的服务名则为类名
android:icon -------------- 服务的图标
android:permission ------- 申明此服务的权限,这意味着只有提供了该权限的应用才能控制或连接此服务
android:process ---------- 表示该服务是否运行在另外一个进程,如果设置了此项,那么将会在包名后面加上这段字符串表示另一进程的名字
android:enabled ---------- 如果此项设置为 true,那么 Service 将会默认被系统启动,不设置默认此项为 false
android:exported --------- 表示该服务是否能够被其他应用程序所控制或连接,不设置默认此项为 false