Xamarin.Android でのサービスの開始

Started Services の概要

通常、開始されたサービスは、クライアントに直接フィードバックや結果を提供することなく、1 つの作業単位を実行します。 作業単位の例として、ファイルをサーバーにアップロードするサービスがあります。 クライアントは、デバイスから Web サイトにファイルをアップロードするようにサービスに要求します。 サービスはファイルを静かにアップロードし (アプリにフォアグラウンドにアクティビティがない場合でも)、アップロードが完了すると終了します。 開始されたサービスがアプリケーションの UI スレッドで実行されることを認識することが重要です。 つまり、サービスが UI スレッドをブロックする作業を実行する場合は、必要に応じてスレッドを作成して破棄する必要があります。

バインドされたサービスとは異なり、"純粋" に開始されたサービスとそのクライアントの間に通信チャネルはありません。 つまり、開始されたサービスでは、バインドされたサービスとは異なるライフサイクル メソッドが実装されます。 次の一覧は、開始されたサービスの一般的なライフサイクル メソッドを示しています。

  • OnCreate – サービスが最初に開始されたときに 1 回呼び出されます。 ここで初期化コードを実装する必要があります。
  • OnBind – このメソッドは、すべてのサービス クラスで実装する必要があります。ただし、開始されたサービスには通常、クライアントがバインドされているわけではありません。 このため、開始されたサービスは単に返されます null。 これに対し、ハイブリッド サービス (バインドされたサービスと開始されたサービスの組み合わせ) は、クライアント用に実装して返す Binder 必要があります。
  • OnStartCommand – システムへの呼び出しまたはシステムによる再起動に応答して、サービスを開始する StartService 各要求に対して呼び出されます。 ここで、サービスは実行時間の長いタスクを開始できます。 このメソッドは、 StartCommandResult メモリ不足によるシャットダウン後にシステムがサービスの再起動を処理する方法または処理する必要があるかどうかを示す値を返します。 この呼び出しはメイン スレッドで行われます。 この方法については、以下でさらに詳しく説明します。
  • OnDestroy – このメソッドは、サービスが破棄されるときに呼び出されます。 これは、必要な最終的なクリーンアップを実行するために使用されます。

開始されたサービスの重要な方法は、メソッドです OnStartCommand 。 これは、サービスが何らかの作業を行う要求を受け取るたびに呼び出されます。 次のコード スニペットは、次の例です OnStartCommand

public override StartCommandResult OnStartCommand (Android.Content.Intent intent, StartCommandFlags flags, int startId)
{
    // This method executes on the main thread of the application.
    Log.Debug ("DemoService", "DemoService started");
    ...
    return StartCommandResult.Sticky;
}

最初のパラメーターは、実行する Intent 作業に関するメタデータを含むオブジェクトです。 2 番目のパラメーターには、 StartCommandFlags メソッド呼び出しに関する情報を提供する値が含まれています。 このパラメーターには、次の 2 つの値のいずれかが含まれます。

  • StartCommandFlag.Redelivery– これは、前IntentIntent配信の再配信であることを意味します. この値は、サービスが返されたが、適切に StartCommandResult.RedeliverIntent シャットダウンされる前に停止された場合に提供されます。 -StartCommandFlag.Retry ‐ この値は、以前の呼び出しが失敗し、Android が前回 OnStartCommand 失敗した試行と同じ意図でサービスを再び開始しようとしたときに受信されます。

最後に、3 番目のパラメーターは、要求を識別するアプリケーションに固有の整数値です。 複数の呼び出し元が同じサービス オブジェクトを呼び出す可能性があります。 この値は、サービスを停止する要求を、サービスを開始する特定の要求に関連付けるために使用されます。 詳細については、「サービスの停止」セクションで説明 します

この値 StartCommandResult は、リソースの制約によりサービスが強制終了された場合の処理に関する提案として、Android に対する提案としてサービスによって返されます。 次の 3 つの値が StartCommandResult考えられます。

  • StartCommandResult.NotSticky – この値は、強制終了したサービスを再起動する必要はないことを Android に示します。 この例として、アプリ内のギャラリーのサムネイルを生成するサービスを検討してください。 サービスが強制終了された場合、サムネイルをすぐに再作成することは重要ではありません。次回アプリを実行するときにサムネイルを再作成できます。
  • StartCommandResult.Sticky – これは、サービスを再起動するように Android に指示しますが、サービスを開始した最後の意図は提供しません。 処理する保留中の意図がない場合は、 null Intent パラメーターに a が指定されます。 その例として、音楽プレーヤー アプリが考えられます。サービスは音楽を再生する準備ができて再起動しますが、最後の曲が再生されます。
  • StartCommandResult.RedeliverIntent – この値は、サービスを再起動して最後 Intentのサービスを再配信するように Android に指示します。 この例は、アプリのデータ ファイルをダウンロードするサービスです。 サービスが強制終了した場合でも、データ ファイルをダウンロードする必要があります。 返すことで StartCommandResult.RedeliverIntent、Android がサービスを再起動すると、サービスに意図 (ダウンロードするファイルの URL が保持されます) も提供されます。 これにより、ダウンロードを再起動または再開できます (コードの正確な実装に応じて)。

の 4 番目のStartCommandResultStartCommandResult.ContinuationMask値があります。 この値は返され、Android が強制終了した OnStartCommand サービスを継続する方法について説明します。 通常、この値はサービスの開始には使用されません。

開始されたサービスの主要なライフサイクル イベントを次の図に示します。

ライフサイクル メソッドの呼び出し順序を示す図ライフサイクル メソッドの呼び出

サービスの停止

開始されたサービスは無期限に実行され続けます。Android は、十分なシステム リソースがある限り、サービスを実行し続けます。 クライアントがサービスを停止する必要があるか、サービスが作業を完了したときにサービス自体が停止する可能性があります。 サービスを停止するには、次の 2 つの方法があります。

  • Android.Content.Context.StopService() – クライアント (アクティビティなど) は、メソッドを呼び出すことによってサービス停止を StopService 要求できます。

    StopService(new Intent(this, typeof(DemoService));
    
  • Android.App.Service.StopSelf() – サービスは、次のコマンドを StopSelf呼び出すことによってシャットダウンできます。

    StopSelf();
    

startId を使用してサービスを停止する

複数の呼び出し元は、サービスの開始を要求できます。 未処理の開始要求がある場合、サービスは渡されたOnStartCommand要求をstartId使用して、サービスが途中で停止されるのを防ぐことができます。 これは startId 、最新の呼び出しに StartService対応し、呼び出されるたびにインクリメントされます。 したがって、後続の要求StartServiceがまだ呼び出しに至っていない場合、サービスは呼び出しを行い、(単にStopSelf呼び出OnStartCommandStopSelfResultすのではなく) 受信した最新のstartId値を渡すことができます。 呼び出しで対応する呼び出しがまだ発生していない場合、呼び出StartServiceしでStopSelf使用される呼び出しが最新StartServicestartId呼び出OnStartCommandしに対応しないため、システムはサービスを停止しません。