【Kotlin/Android Studio】Serviceとは?種類とバックグラウンド操作

この記事からわかること

  • Android Studio/KotlinService使い方
  • サービス種類実装方法

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

Serviceとは?

Serviceとはバックグラウンドなどで長時間処理を実装したい場合に使用するUIを実装しないアプリコンポーネントです。

サービスの役割はアプリを操作していない間に処理を行うことです。ユーザーがアプリを操作している間に限り処理をメインスレッド以外で実行したい場合は別のスレッドを使用することが推奨されています。

例えばActivityが実行している間だけ音楽を流す場合はActivityのライフサイクルのonCreate()でスレッドを作成し、onStart()で実行を開始して、onStop()で停止するべきだと公式に記述されています。

そうではなくアプリが起動している間音楽を流したい場合ActivityではActivityが破棄されるたびに音楽が止まってしまうのでバックグラウンドで処理を継続して実行できるサービスを使用します。

Serviceでできること

バックグラウンドスレッドでの処理の実行はKotlin Coroutines、バックグラウンド(アプリ停止やキル状態)での処理の継続にはWorkManagerなどを使用する方法もあります。

サービスの種類

AndroidのServiceは3種類に分かれています。

Foreground Service

ユーザーが認識できる操作を行うサービス。Foregroundとあるが実際にはバックグラウンドで動作している。例えば音楽を再生するなど。ユーザーがアプリを操作していない間も動作する。

Foregroundとなっている理由は処理を実行中に実行している内容の通知を表示する必要があるため。

Background Service

ユーザーには直接認識できない操作を行うサービス。API操作やファイルの読み込みや書き込みなど内部的な操作を行いたい場合に使用する。

Bind Service

他のコンポーネント(Activityなど)からbindServiceメソッドを使用してバインドされた状態のサービス。コンポーネントからサービスを操作することができる。サービスは複数のコンポーネントからバインドすることができ、全てアンバインドされるとサービスが破棄される。

Serviceの実装方法

流れ

  1. Serviceを継承したクラスの作成
  2. マニフェストファイルへ追記
  3. Serviceを呼び出す

1.Serviceを継承したクラスの作成

いずれのServiceも実装するためにはServiceを継承したサブクラスを定義します。Serviceもライフサイクルを保持しているのでオーバーライドして処理を実装して行きます。

onStartCommandメソッドは実際にサービスで操作したい処理を記述する部分です。返り値としてサービスが突然Killされた場合の挙動を返します。

またonStartCommandメソッド内はデフォルトではUIスレッド(メインスレッド)で実行されます。

class ExampleService : Service() {

  override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    Log.d("Service", "onStartCommand")
    Log.d("Service", Thread.currentThread().getName()) // main

    // Intent経由でデータを受け取れる
    intent?.getStringExtra("msg")?.let {
        Log.d("Intent:", it)
    }
    // 返り値にサービスが突然Killされた場合の動作を返す
    return START_NOT_STICKY // サービスの再起動なし
  }

  override fun onCreate() {
    super.onCreate()
    Log.d("Service", "サービスが作成されたよ")
  }

  override fun onDestroy() {
    super.onDestroy()
    Log.d("Service", "サービスが破棄されたよ")
  }

  override fun onBind(intent: Intent): IBinder {
    Log.d("Service", "サービスがバインドされたよ(Bind Service)")
  }

  override fun onTaskRemoved(rootIntent: Intent?) {
    super.onTaskRemoved(rootIntent)
    Log.d("Service", "タスクが削除されたよ")
  }
}

START_NOT_STICKY

再起動なし。

START_STICKY

再起動しonStartCommandメソッドを呼び出す。ただし再起動時にインテントがnullになることがある。

START_REDELIVER_INTENT

再起動しonStartCommandメソッドを呼び出す。最後に渡されたインテントを再度サービスに渡す。

2.マニフェストファイルへ追記

プロジェクト内にServiceを追加した場合は「AndroidManifest.kt」へ追加したServiceを明記する必要があります。新規ファイルを追加する際に「Service」を選択していればここは自動で記述してくれます。


<manifest ...>
  ...
  <application ...>

    <service
      android:name=".ExampleService"
      android:enabled="true"
      android:exported="false" />

  </application>
</manifest>

android:enabled

Serviceがシステムによって実行可能かどうか。

android:exported

他のアプリケーションからサービスが起動されるかどうか。

3.Serviceを呼び出す

ActivityからServiceを呼び出す際はstartServiceメソッドを使用します。引数にIntentを渡すことで値を渡すことも可能です。実行されたサービスを停止するためにはstopServiceメソッドを使用します。

おすすめ記事:【Kotlin/Android Studio】Intentとは?Activity間のデータの受け渡し

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val buttonStart: Button = findViewById(R.id.button)
        val buttonStop: Button = findViewById(R.id.button2)

        buttonStart.setOnClickListener {
            val intent = Intent(this, ExampleService::class.java)
            intent.putExtra("msg", "Hello World!!")
            startService(intent)

            buttonStart.isEnabled = false
            buttonStop.isEnabled = true
        }

        buttonStop.setOnClickListener {

            val intent = Intent(this, ExampleService::class.java)
            stopService(intent)

            buttonStart.isEnabled = true
            buttonStop.isEnabled = false
        }
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index