search
LoginSignup
5
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

【Kotlin研修10日目】バックグラウンド処理の実装、サービスのライフサイクル

バックグラウンド処理

アクティビティから独立したサービスによってメインスレッド上で実行される、ユーザから直接認識されず、ユーザによって操作を受けない処理。

サービス

アクティビティから独立してバックグラウンド処理を実行する仕組み(=コンポーネント)。

サービスのライフサイクル

サービスのライフサイクルは以下の通り。

アクティビティstartService()メソッドによってサービスの初期化が行われ、自動的にActive状態へと移行する。

また、アクティビティまたはサービス自身によるサービスの終了時にInactive状態へと遷移する。

なお、Serviceクラスを継承するサービスクラスでは、以下のメソッドと抽象メソッドであるonBind()メソッドをオーバーライドする際に、親(=super)であるServiceクラスのメソッドを呼び出す必要がない

ライフサイクル メソッド 呼び出しタイミング
Initialized onCreate() サービスの起動
=アクティビティstartService()
Active onStartCommand() サービスの開始
Inactive onDestroy() サービスの終了
=アクティビティstopService()
または
サービスクラスstopSelf()

サービスのライフサイクル.png
出典

バックグラウンド処理の実装

バックグラウンド処理を実装する手順は、以下の通り。

  1. Serviceクラスを継承するサービスクラスの作成
  2. マニフェストファイル(=AndroidManifest.xml)に、1.で作成したサービスを登録
  3. サービスクラスバックグラウンド処理を記述
  4. アクティビティからサービスを起動
  5. アクティビティまたはサービスクラス内部からサービスを終了

サービスクラスの作成

Serviceクラスを継承するサービスクラスは、プロジェクトServiceファイルを新規作成して記述する。

サンプルコード

SoundManageService.kt
class SoundManageService : Service() {
    // Serviceクラスの抽象メソッドの実装(必須)
    // -> サービスをバインドして実行する場合はブロック内{...}に処理を記述
    override fun onBind(intent: Intent): IBinder {}

    // サービスの初期化時に実行する処理
    override fun onCreate() {
        ...
    }

    // サービスの実行開始時に行う処理
    // -> サービスの強制終了時の処理を表すServiceクラス定数を返却
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        ...
        return <Serviceクラス定数>
    }

    // サービスの終了時に実行する処理
    override fun onDestroy() {
        ...
    }
}

マニフェストファイルへのサービスの登録

マニフェストファイル(=AndroidManifest.xml)に、serviceタグを記述してサービスを登録する。
Android StudioではServiceファイルの生成と同時に自動的に追記される

serviceタグの属性

属性名 ウィザード入力欄 内容
android:name Class Name サービスクラス名
android:enabled Exported 利用可否
true: 利用可能
false: 利用不可
android:exported Enabled 外部アプリからの利用可否
true: 外部から利用可能
false: 内部のみ利用可能

サンプルコード

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    ...
    <application ...>
        <service
            android:name=".SoundManageService"
            android:enabled="true"
            android:exported="false">
        </service>
        ...
    </application>
</manifest>

バックグラウンド処理の記述

実行するバックグラウンド処理は、サービスの開始時に呼び出されるonStartCommand()のブロック{...}内に記述する。

また、onStartCommand()メソッドは、返り値として「サービス強制終了した場合のサービスのリカバリ方法」を表すServiceクラス定数が必要となる。

Serviceクラス定数

定数 内容
START_NOT_STICKY 自動で再起動しない
※常駐必須のサービスでない場合に推奨
START_STICKY 自動で再起動する
インテントnull
START_REDELIVER_INTENT 自動で再起動する
インテントは直前に保持していた値

サンプルコード

SoundManageService.kt
class SoundManageService : Service() {
    ...
    // サービスの実行開始時に行う処理
    // -> サービスの強制終了時の処理を表すServiceクラス定数を返却
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        ...  // バックグラウンド処理を記述

        // Serviceクラス定数の返却
        return START_NOT_STICKY
    }
    ...
}

アクティビティによるサービスの起動

参考1: インテントとインテントフィルタ
参考2: 研修3日目
アクティビティからサービスを起動する場合、アクティビティサービスクラスの橋渡し役となるインテント(=Intentオブジェクト)を生成し、インテントを通じてサービスを起動する。

定義

// Intentオブジェクトの生成
Intent(packageContext: Context!, cls: Class<*>!)
// パラメータ
// packageContext: 遷移元のアクティビティオブジェクト(=コンテキスト)
// cls: Javaクラス化した遷移先アクティビティ
// -> KotlinのクラスをJavaに変換する場合は、"<Kotlinクラス名>::class.java"と記述

// インテントを通じたサービスの起動
Context.startService(service: Intent!): ComponentName?
// パラメータ
// service: サービスを保持するIntentオブジェクト

サンプルコード

MainActivity.kt
// Intentオブジェクト
val intent = Intent(this@MainActivity, SoundManageService::class.java)

// サービスの起動
startService(intent)

サービスの終了

サービスを終了する方法は、以下の2通り。

  1. アクティビティ(=サービスクラス外部)のstopService()
  2. サービス自身(=サービスクラス内部)のstopSelf()

定義

// アクティビティ(サービスクラス外部)によるサービスの終了
Context.stopService(service: Intent!): Boolean
// パラメータ
// service: サービスを保持するIntentオブジェクト

// サービス自身(サービスクラス内部)によるサービスの終了
Service.stopSelf(): Unit

サンプルコード

MainActivity.kt
// Intentオブジェクト
val intent = Intent(this@MainActivity, SoundManageService::class.java)

// アクティビティによるサービスの終了
stopService(intent)
SoundManageService.kt
// サービスクラス自身によるサービスの終了
stopSelf()

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5
Help us understand the problem. What are the problem?