サービスの起動とバインド

序文

Android の開発過程では、さまざまな場面で Service が登場します。このように重要な Android コントロールですが、開発時にさらに便利になるように、そのさまざまな詳細を理解する必要もあります。

Androidのサービスとは何ですか?

Google の公式ドキュメントによると、Service はバックグラウンドで長時間実行される操作を実行するアプリケーション コンポーネントですが、これらの操作はユーザーと直接対話するものではなく、他のアプリケーションが使用する基本的な機能を提供します。インターフェイスなしでアクティビティを見る、つまり、ユーザーはサービスがどのようなものであるかを直接見ることはできませんが、バックグラウンドで提供される機能を通じてサービスの存在を認識できます。アクティビティに関する限り、それは直接目に見えます。ユーザーに提供する機能を、ビューを通じてユーザーの目の前に直接表示することもできます。

1.0 サービスとアクティビティの関係

ServiceとActivityの関係図

上記の UML 図からわかるように、Service と Activity の間の継承関係は、最終的にはすべて抽象クラス Context から継承します。抽象クラス Context にとって、それはアプリケーションのグローバル情報のインターフェイスであり、その実装は次のとおりです。 Android システムによって提供され、アプリケーション固有のリソースとクラスへのアクセスを提供するだけでなく、アクティビティの起動、ブロードキャスト、インテントの受信などのアプリケーション レベルの操作の呼び出しも提供します。ただし、Service は、Activity よりも ContextThemeWrapper クラスを継承しません。

2.0 サービスを開始する 2 つの方法とそれに対応するライフサイクル

2.1 startService() でサービスを開始する

startService()でサービスを開始するフローチャート

startService() でサービスを開始する

startService() でサービスを開始します。システムはonCreate()メソッドとonStartConnect()メソッドをコールバックします。stopService()サービスを閉じるために最初のメソッドを呼び出さない場合は、startService()メソッドを再度呼び出して SerVice を開始するだけです。onCreate() メソッドは呼び出されません。再び呼び出されますが、onStartConnect()メソッドはstartService()呼び出される回数とコールバックする回数になります。もう 1 つ注意すべき点は、サービスはメソッドで開始されますが、呼び出されるメソッドstartService()がない場合は、開始したコンポーネントが終了する前にサービスが終了することです。サービスを停止すると、ユーザーがプロセスを確認するまでサービスはバックグラウンドで実行され続けます。強制終了するか、システム メモリが不足している場合、システムはサービスを強制的に終了します。開始するメソッドがonStopService()何回呼び出されても、サービスは強制的に終了します。サービスを停止するには、メソッドを 1 回startService()呼び出すだけで済みます。このメソッドに関して注意すべき点の 1 つは、このメソッドを呼び出したサービスにまだオブジェクト バインディングがあり、このフラグが設定されている場合、これらのバインディングが削除されるまでサービスは破棄されないことです。stopService()
stopService()ServiceConnectionBIND_AUTO_CREATE

startService() によるサービス開始の概念図

2.2bindService()でサービスを開始する

bindService() でサービス フローチャートを開始する

bindService() でサービス フローチャートを開始する

と同様startService()に、bindService()メソッドもContext抽象クラスの抽象クラス メソッドです。bindService()この方法で開始されたサービスの場合、そのライフ サイクルはスターターのライフ サイクルに関連します。たとえば、サービスがbindService()アクティビティで開始された場合、アクティビティが終了すると、サービスもバインド解除されて破棄されますが、この方法でサービスを破棄すると、次の図に示すように、プログラムが例外 (Exception) を報告することに注意してください。

これは主にサービス接続のオーバーフロー例外です。ただし、プログラムが例外を報告した後も、サービスは引き続きonUnbind()メソッドとonDestroy()メソッドを実行します。

現在はこの方法が主に紹介されていますContext.bindService(Intent, ServiceConnection, int)このメソッドは Context 抽象クラスにあり、抽象メソッドです。このメソッドは 3 つのパラメータを取ります。

パラメータ
意図 接続して開始する必要があるサービスを定義します。暗黙的なインテント (アクション、カテゴリなど) を通じてサービスを開始することも、明示的なインテント (つまり、サービスの名前を直接指定する) を通じてサービスを開始することもできます。 )。
サービス接続 bindService()これはメソッドによって起動されたサービスの開始と停止の状態を主に監視する監視機能であり、これらの 2 つの状態が発生した場合、それぞれonServiceConnected(ComponentName, IBinder)とのメソッドがコールバックされますonServiceDisconnected(ComponentName)このパラメータを空にすることはできません。つまり、空のオブジェクトを渡すことはできません。
整数 渡されるのは、サービスをバインドする方法を定義する Context 関数の定数です。

Context.bindService(Intent, ServiceConnection, int)関数内のパラメータについてはint(Google から翻訳):

整数
BIND_AUTO_CREATE サービスは、バインディングが存在する限り自動的に作成されます。これによりサービスが作成されますが、そのonStartCommand(Intent, int, int)メソッドは明示的な呼び出しの結果としてのみ呼び出されることに注意してくださいstartService(Intent)そうでない場合でも、サービスの作成時にサービス オブジェクトにアクセスできるようになります。ICE_CREAM_SANDWICHこのフラグを指定しないと、対象のサービス プロセスを考慮したシステムの重要度にも影響することに注意してください。設定されている場合、それを高める唯一の方法はバインドされたサービスを使用することです。この場合、問題となるのはそのアクティビティがフォアグラウンドにある場合のみです。この動作を実現するには、新しいフラグを明示的に指定する必要がありますBIND_ADJUST_WITH_ACTIVITY互換性を確保するために、指定されていないレガシー アプリケーションには、同じ結果を達成するためのBIND_AUTO_CREATEフラグが自動的に設定されます。BIND_WAIVE_PRIORITY并 BIND_ADJUST_WITH_ACTIVITY
BIND_DEBUG_UNBIND バインドを解除するための不一致呼び出しのデバッグ ヘルプ。このフラグが設定されている場合、unbindService(ServiceConnection)後続の呼び出しの呼び出しスタックが保存され、後で間違ったアンバインド呼び出しが行われた場合に出力されます。これを行うには、アプリケーションの存続期間中バインディングに関する情報を保持する必要があり、リークが発生することに注意してください。これはデバッグにのみ使用してください。
BIND_NOT_FOREGROUND このバインディングでは、ターゲット サービスのプロセスをフォアグラウンド スケジューリング優先順位に上げることはできません。クライアントと少なくとも同じメモリ優先度に昇格されますが (クライアントが強制終了できない場合でも、そのプロセスは強制終了されません)、CPU スケジューリングのためにバックグラウンドに残される可能性があります。これは、バインディング クライアントがフォアグラウンド プロセスであり、ターゲット サービスがバックグラウンド プロセスである場合にのみ効果があります。
BIND_ABOVE_CLIENT このサービスにバインドされているクライアント アプリケーションが、アプリケーション自体よりもサービスを重要であると見なしていることを示します。設定すると、プラットフォームは低メモリ キラーによってアプリケーションを強制終了させ、次にアプリケーションがバインドされているサービスを強制終了させようとしますが、これは保証されません。
BIND_ALLOW_OOM_MANAGEMENT バインドされたサービスをホストするプロセスが通常のメモリ管理を実行できるようにします。これは、より実行中のサービスのように扱われ、メモリ不足またはその他の考えられる場合にシステムがプロセスを (一時的に) クリーンアップできるようになり、実行された場合にはより積極的に強制終了 (および再起動) される候補になります。長い間。
BIND_WAIVE_PRIORITY ターゲット サービス ホスト プロセスのスケジューリングやメモリ管理の優先順位には影響しません。バックグラウンドでの通常のアプリケーション プロセスと同様に、サービスのプロセスがバックグラウンド LRU リストで管理できるようにします。

3.0 ハイブリッド起動およびシャットダウン サービス

  • Content.startService() で開始されたサービスの場合、開始されたコンポーネントはサービス内のメソッドを呼び出すことはできませんが、この方法で開始されたサービスはシステムのバックグラウンドで長時間実行されます。
  • Context.bindService() によって開始されたサービスの場合、開始されたコンポーネントはバインダーを介してサービス内のメソッドを呼び出すことができますが、この方法で開始されたサービスのライフ サイクルは、それを開始したコンポーネントのライフ サイクルに関連します。
そのような状況がある場合:

需要一个长期运行在后台的服务,同时需要调用服务里面的方法,应该怎么启动 Service ? 例如音乐播发器?

現時点では、Service のハイブリッド起動を行う必要があります。最初のContent.startService()モードまたは最初のモードでContext.bindService()開始することが非常に重要です。

以下は、ハイブリッド スタートアップの図です。

ハイブリッド起動の一般的なロジック:

  • まず、Content.startService()サービスがバックグラウンドで長時間実行できるように、 の方法で開始されます。
  • 次に、Context.bindService()操作サービス内のメソッドのオブジェクト インスタンスを取得する方法でそれを開始します。
  • unbindService()サービス オーバーフロー例外のスローを避けるために、サービスを閉じるために呼び出します。
  • 現時点では、サービスはバックグラウンドで長時間実行されます。

まとめ

このブログは主に Google ドキュメントに基づいて Service のライフサイクルを分析し、 ServiceContent.startService()との類似点とContext.bindService()相違点を主に分析します。次回の記事では、Android の 4 つの主要コンポーネントの 1 つである BroadCast について、著者が皆さんと一緒に分析します。読んでくれてありがとう…


ソースコードのダウンロードStartAndBindServiceTest

おすすめ

転載: blog.csdn.net/HongHua_bai/article/details/78266436