[Android] Service の使い方

Servce はバックグラウンドで作業をさせたい場合に使います。システムは直ぐにスリープに入れてしまいます。それでも裏で色々やりたい場合に有効です。例えば音楽の再生など

Android Studio
2024.1.1




Service

 

Serviceがバックグラウンドで動作するので、非同期と勘違いしそうですがそうではなく、Activityから表示UIを無くしたようなコンポーネントです。

サービスは、そのホスティング プロセスのメインスレッドで実行され、サービスが自身のスレッドを作成することはなく、別のプロセスで実行されることもありません
CPU を集中的に使う作業、Audioの再生やネットワーク作業など、を行う場合は、サービス内に新しいスレッドを作成してその作業を行う必要があります
 

 

Serviceの開始

 

Serviceを開始するには、

  1. startService()
    • 開始後は、開始したActivityが破棄されても基本的には実行し続けられる、Activityとは別の独自のContextを持っている
    • 呼び出し側からの制御は開始か停止させるのみで、タスクの終了をコールバックしないので自身で終了するなどの手当が必要
  2. bindService()
    • 要求を送信したり、結果を取得したりとServiceを制御できますが、呼び出し元のActivityが終了すると一緒に終了してしまう

これにAndroid 8.0からの追加として、

startForegroundService()

を使ってバックグラウンド実行制限をある程度回避できます。

ForegroundServicehは、

  • API レベル 29 以降:location サービスタイプを使用して、位置情報を使用するすべてのフォアグラウンド サービスを宣言する必要があります。
  • API レベル 30 以降: カメラまたはマイクを使用するすべてのフォアグラウンド サービスを、それぞれ camera または microphone サービスタイプを使用して宣言する必要があります。
  • API レベル 34 以降: すべてのフォアグラウンド サービスを、そのサービスタイプとともに宣言する必要があります。

ということで、相変わらず変更が多いです

 

startService()

 

Activity からServiceを呼び出すのはIntent をセットして、startService(intent) で行います。
 

 
Activity から Activity に遷移させる場合は
startActivity(intent)でしたので、startService(intent)に変わっただけとわかりやすです
 
一方、サービス側は

 
Service を継承して

  1. onCreate()
    • これはActivity同様、最初だけ呼ばれて終わりなので初期化だけです。
  2. onStartCommand()
    • サービスで実行させたいコードはここに記述
    • 戻り値は:
      • START_NOT_STICY:強制終了しても再起動しない
      • START_STICKY:強制終了されても自動的にサービスが再起動、最後のインテントは再配信しない
      • START_REDELIVER_INTENT:強制終了されても自動的にサービスが再起動、サービスに最後に配信されたインテントで onStartCommand() を呼び出す
  3. onDestroy()
  4. onBind()
    • bindService() で呼び出した場合
      onStartCommand() ではなく
      onBind() がcallbackされます

 

Manifest にサービスクラスの定義を忘れないように

パーミッション
サービスタイプの指定

AndroidManifest.xml

 

 

Serviceの終了

 

startService()で始めたServiceは勝手には止まりません。
 
MainActivityからstopService(intent)で止める
 

 
ミュージック再生などのタスクが終了したのを受けてstopSelf()を実行することもできます。
 

 
Oreoからバックグラウンドに対する制限ができて

アプリがバックグラウンドに移行すると数分間のウィンドウが提供され、アプリはそのウィンドウ内でサービスを作成して使用できます。
 
そのウィンドウの終了時に、アプリはアイドル状態であると見なされます。 システムはこの時点で、アプリがサービスのService.stopSelf()メソッドを呼び出したかのように、アプリのバックグラウンド サービスを停止します。

バックグラウンド実行制限 | Android Developers 

またマルチタスクメニューからアプリをユーザーが終了させることもあります。

 

startForegroundService()

 

バックグラウンドでアプリが実行できないと、一番困るのはmusic系のアプリでしょうか、それについては
バックグラウンド実行制限 | Android Developersにはこのような一文があります。

Android 8.0 では、追加機能があります。システムは、バックグラウンド アプリによるバッグラウンド サービスの作成を許可しません。
そのため、Android 8.0 では、フォアグラウンドで新しいサービスを作成する Context.startForegroundService() メソッドが新たに導入されています。

システムによってサービスが作成されると、アプリは、サービスの startForeground() メソッドを 5 秒以内に呼び出して、
その新しいサービスの通知をユーザーに表示します。
アプリが startForeground() を制限時間内に呼び出さない場合、サービスが停止し、アプリが ANR になります。

ということでこれを使ってMediaPlayerでをServiceで音楽再生してみます。

また、フォアグラウンド サービスタイプの設定が必要です
 

Android 14 以上をターゲットとするアプリに影響する Android 14 の変更をご確認ください。

 

 

サンプルコード

 

ActivityからServiceを開始し、Service内で5秒以内にstartForegroundを呼び出します。

これでステータスバーにはアイコンが表示されてForgroundにいるかのようになります

1x1.trans - [Android] Service の使い方

Screenshot

 

マニュフェストには、音楽再生なのでMediaPlaybackとして

  • FOREGROUND_SERVICEのpermission設定とサービスタイプのpermission
  • <service … />の追加とサービスタイプの指定
    • android:foregroundServiceType=”mediaPlayback”
  • バックグラウンドに入った後で、通知からActivityを起動させるための<activity>設定
    • android:taskAffinity=””
    • android:excludeFromRecents=”true”

 

AndroidManifest.xml

 

MainActivityではServiceの開始とストップのためのボタンを設置

MainActivity.java

 
サービス側では、MediaPlayerを使ってmp3を再生させてみます。
MediaPlayerについてはこちらで解説しています。

mediaplyer a01 100x100 - [Android] Service の使い方
MediaPlayer()を使って簡単な音楽再生アプリが作れます。Audioを扱うものとしては他にはSoundPoolやAudioTrack...

Rawフォルダーを作成して適当なmp3の音楽ファイルを入れておきます。

1x1.trans - [Android] Service の使い方


以下のJavaクラスを作成しコーディング

TestService.java

 
以下にレイアウトやリソースがあります

レイアウトです。簡単にするためLinearLayoutを使いました。
activity_main.xml

 
strings.xml

 
これでアプリを終了、マルチタスクメニューから削除してもmp3が再生されています。
 

フォアグラウンドサービスはAPIによって変更が多々あるので確認が必要です
 


 

 
関連ページ:

 

References:
サービス | Android Developers
バックグラウンド実行制限 | Android Developers
Service | Android Developers

シェアする

  • このエントリーをはてなブックマークに追加

フォローする