Xamarin.Android のインテント サービス
開始されたサービスとバインドされたサービスの両方がメイン スレッドで実行されます。つまり、円滑なパフォーマンスを維持するには、サービスでは作業を非同期で実行する必要があります。 この問題に対処する最も簡単な方法の 1 つはワーカー キュー プロセッサ パターンを利用することです。このパターンでは、行われるべき作業は、1 つのスレッドによってサービスが提供されるキュー内に置かれます。
IntentService
は、このパターンの Android 固有実装を提供する Service
クラスのサブクラスです。 キュー処理、キューにサービスを提供するためのワーカー スレッドの起動、ワーカー スレッドで実行するキューの pull request を管理します。 IntentService
は、キューに作業がなくなると、自ら静かに停止し、ワーカー スレッドを削除します。
作業は、Intent
を作成し、その Intent
を StartService
メソッドに渡すことでキューに送信されます。
動作中、OnHandleIntent
メソッド IntentService
は停止も中断もできません。 この設計のため、IntentService
はステートレスの状態を維持する必要があります。アプリケーションの残りの部分からのアクティブな接続や通信に依存しないようにしてください。 IntentService
は、作業要求をステートレスに処理するためのものです。
IntentService
のサブクラス化には、次の 2 つの要件があります。
- 新しい型 (
IntentService
のサブクラス化によって作成) は、OnHandleIntent
メソッドのみをオーバーライドします。 - 新しい型のコンストラクターには、要求を処理するワーカー スレッドに名前を付けるための文字列が必要です。 このワーカー スレッドの名前は、主にアプリケーションのデバッグ時に使用されます。
次のコード例では、オーバーライドされた OnHandleIntent
メソッドで IntentService
が実装されます。
[Service]
public class DemoIntentService: IntentService
{
public DemoIntentService () : base("DemoIntentService")
{
}
protected override void OnHandleIntent (Android.Content.Intent intent)
{
Console.WriteLine ("perform some long running work");
...
Console.WriteLine ("work complete");
}
}
作業は Intent
をインスタンス化し、パラメーターとしてそのインテントを使用して StartService
メソッドを呼び出すことで IntentService
に送信されます。 インテントは、OnHandleIntent
メソッドでパラメーターとしてサービスに渡されます。 このコード スニペットは、インテントに作業要求を送信する例となっています。
// This code might be called from within an Activity, for example in an event
// handler for a button click.
Intent downloadIntent = new Intent(this, typeof(DemoIntentService));
// This is just one example of passing some values to an IntentService via the Intent:
downloadIntent.PutExtra("file_to_download", "http://www.somewhere.com/file/to/download.zip");
StartService(downloadIntent);
このコード スニペットに示されているように、IntentService
ではインテントから価値を抽出できます。
protected override void OnHandleIntent (Android.Content.Intent intent)
{
string fileToDownload = intent.GetStringExtra("file_to_download");
Log.Debug("DemoIntentService", $"File to download: {fileToDownload}.");
}