Android KTX   Android Jetpack の一部。

Android KTX は、Android Jetpack およびその他の Android ライブラリに含まれる Kotlin 拡張機能セットです。KTX の拡張機能によって、Jetpack、Android プラットフォーム、その他の API で、Kotlin が簡潔になってわかりやすくなります。その目的のため、これらの拡張機能では、次のようないくつかの Kotlin 言語機能が活用されています。

  • 拡張関数
  • 拡張プロパティ
  • ラムダ
  • 名前付きパラメータ
  • パラメータのデフォルト値
  • コルーチン

たとえば、SharedPreferences を扱う場合、優先設定データを変更するにはエディタを作成する必要があります。また、次の例のように、編集が完了したら変更を適用または commit する必要があります。

sharedPreferences
        .edit()  // create an Editor
        .putBoolean("key", value)
        .apply() // write to disk asynchronously

Kotlin lambda は、このユースケースに最適です。エディタ作成後に実行するコードのブロックを渡してコードを実行させ、SharedPreferences API に変更をアトミックに適用させることで、より簡潔なアプローチが可能になります。

Android KTX Core 関数 SharedPreferences.edit の一例を次に示します。これにより、編集関数が SharedPreferences に追加されます。この関数は、変更の commit あるいは適用を指示する最初の引数として、オプションの boolean フラグを取ります。また、SharedPreferences エディタで実行するアクションを、ラムダの形式で受け取ります。

// SharedPreferences.edit extension function signature from Android KTX - Core
// inline fun SharedPreferences.edit(
//         commit: Boolean = false,
//         action: SharedPreferences.Editor.() -> Unit)

// Commit a new value asynchronously
sharedPreferences.edit { putBoolean("key", value) }

// Commit a new value synchronously
sharedPreferences.edit(commit = true) { putBoolean("key", value) }

呼び出し元は、変更を commit するか適用するかを選択できます。action ラムダはそれ自体が SharedPreferences.Editor 上の匿名拡張関数であり、署名で示されているとおりに Unit を返します。この理由により、ブロック内部において SharedPreferences.Editor 上で作業を直接実行することが可能になっています。

最後に、SharedPreferences.edit() 署名には inline キーワードが含まれます。このキーワードによって、関数が使用されるたびにその関数のコンパイル済みバイトコードをコピー&ペースト(あるいはインライン)すべきか、Kotlin コンパイラに指示されます。これにより、この関数が呼び出されるたびにすべての action に新しいクラスをインスタンス化する手間がなくなります。

ラムダを使用してコードを渡し、オーバーライド可能な合理的デフォルトを適用し、inline 拡張関数を使用してこれらの動作を既存の API に追加するこのパターンは、Android KTX ライブラリで提供される拡張機能の典型です。

プロジェクトで Android KTX を使用する

Android KTX の使用を開始するには、プロジェクトの build.gradle ファイルに次の依存関係を追加します。

repositories {
    google()
}

AndroidX モジュール

Android KTX は複数のモジュールに整理されており、各モジュールに 1 つ以上のパッケージが含まれます。

各モジュール アーティファクトの依存関係をアプリの build.gradle ファイルに含める必要があります。アーティファクトには必ずバージョン番号を追加してください。最新のバージョン番号は、各アーティファクトに対応するこのトピック内のセクションで確認できます。

Android KTX には、共通フレームワーク API 用の Kotlin 拡張機能と複数のドメイン固有の拡張機能を提供する単一のコアモジュールが含まれています。

コアモジュールを除くすべての KTX モジュール アーティファクトによって、build.gradle ファイル内で基盤となる Java 依存関係を置き換えることができます。たとえば、androidx.fragment:fragment の依存関係を androidx.fragment:fragment-ktx に置き換えることができます。この構文はバージョニング管理の改善に役立ちます。依存関係宣言の要件が追加されることはありません。

Core KTX

Core KTX モジュールによって、Android フレームワークの一部である共通ライブラリに拡張機能が提供されます。これらのライブラリには、build.gradle への追加が必要な Java ベースの依存関係はありません。

このモジュールをインクルードするには、アプリの build.gradle ファイルに次の行を追加します。

dependencies {
    implementation "androidx.core:core-ktx:1.3.0"
}

Core KTX モジュールに含まれるパッケージのリストを次に示します。

Collection KTX

Collection 拡張機能には、ArrayMapLongParseArrayLruCache など、メモリ効率の良い Android のコレクション ライブラリを扱うためのユーティリティ関数が含まれています。

このモジュールを使用するには、アプリの build.gradle ファイルに次の行を追加します。

    dependencies {
        implementation "androidx.collection:collection-ktx:1.1.0"
    }
    

次の例に示すように、Collection 拡張機能は Kotlin の演算子オーバーロードを利用して、コレクション連結などの処理を簡略化します。

// Combine 2 ArraySets into 1.
val combinedArraySet = arraySetOf(1, 2, 3) + arraySetOf(4, 5, 6)

// Combine with numbers to create a new sets.
val newArraySet = combinedArraySet + 7 + 8

Fragment KTX

Fragment KTX モジュールには、フラグメント API を簡略化する拡張機能が多数含まれています。

このモジュールをインクルードするには、アプリの build.gradle ファイルに次の行を追加します。

    dependencies {
        implementation "androidx.fragment:fragment-ktx:1.2.4"
    }
    

Fragment KTX モジュールでは、ラムダを使用してフラグメント トランザクションを簡略化できます。次に例を示します。

fragmentManager().commit {
   addToBackStack("...")
   setCustomAnimations(
           R.anim.enter_anim,
           R.anim.exit_anim)
   add(fragment, "...")
}

また、viewModels および activityViewModels プロパティ デリゲートを使用して ViewModel を 1 行にバインディングすることもできます。

// Get a reference to the ViewModel scoped to this Fragment
val viewModel by viewModels<MyViewModel>()

// Get a reference to the ViewModel scoped to its Activity
val viewModel by activityViewModels<MyViewModel>()

Lifecycle KTX

Lifecycle KTX は、個々の Lifecycle オブジェクトに対する LifecycleScope を定義します。このスコープ内で起動されたすべてのコルーチンは、Lifecycle が破棄されたときにキャンセルされます。LifecycleCoroutineScope にアクセスするには、lifecycle.coroutineScope または lifecycleOwner.lifecycleScope プロパティを使用します。

このモジュールをインクルードするには、アプリの build.gradle ファイルに次の行を追加します。

    dependencies {
        implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
    }
    

次の例は、lifecycleOwner.lifecycleScope を使用して計算済みテキストを非同期で作成する方法を示しています。

class MyFragment: Fragment() {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewLifecycleOwner.lifecycleScope.launch {
            val params = TextViewCompat.getTextMetricsParams(textView)
            val precomputedText = withContext(Dispatchers.Default) {
                PrecomputedTextCompat.create(longTextContent, params)
            }
            TextViewCompat.setPrecomputedText(textView, precomputedText)
        }
    }
}

LiveData KTX

LiveData を使用する際に、値を非同期で計算することが必要になる場合があります。たとえば、ユーザーの優先設定を取得して UI に提供する場合などです。このようなケースのために、LiveData KTX には、suspend 関数を呼び出して結果を LiveData オブジェクトとして提供する liveData ビルダー関数が用意されています。

このモジュールをインクルードするには、アプリの build.gradle ファイルに次の行を追加します。

    dependencies {
        implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"
    }
    

次の例で、loadUser() は別の場所で宣言された中断関数です。liveData ビルダー関数を使用して loadUser() を非同期で呼び出し、次に emit() を使用して結果を出力できます。

val user: LiveData<User> = liveData {
    val data = database.loadUser() // loadUser is a suspend function.
    emit(data)
}

LiveData でのコルーチンの使用の詳細については、アーキテクチャ コンポーネントで Kotlin コルーチンを使用するをご覧ください。

Navigation ライブラリの各コンポーネントには、API をより簡潔にして Kotlin で使いやすいように適応させる独自の KTX バージョンがあります。

これらのモジュールをインクルードするには、アプリの build.gradle ファイルに次の行を追加します。

dependencies {
    implementation "androidx.navigation:navigation-runtime-ktx:2.3.0-beta01"
    implementation "androidx.navigation:navigation-fragment-ktx:2.3.0-beta01"
    implementation "androidx.navigation:navigation-ui-ktx:2.3.0-beta01"
}

次の例に示すように、拡張関数とプロパティ委任を使用して宛先引数にアクセスし、宛先に移動します。

class MyDestination : Fragment() {

    // Type-safe arguments are accessed from the bundle.
    val args by navArgs<MyDestinationArgs>()

    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        view.findViewById<Button>(R.id.next)
            .setOnClickListener {
                // Fragment extension added to retrieve a NavController from
                // any destination.
                findNavController().navigate(R.id.action_to_next_destination)
            }
     }
     ...

}

Palette KTX

Palette KTX モジュールは、カラーパレット作業時に Kotlin を使いやすくするためのサポートを提供します。

このモジュールを使用するには、アプリの build.gradle ファイルに次の行を追加します。

    dependencies {
        implementation "androidx.palette:palette-ktx:1.0.0"
    }
    

たとえば、Palette インスタンスを扱う場合、get 演算子([ ])を使用して、指定された target 向けに selected 見本を取得できます。

val palette = Palette.from(bitmap).generate()
val swatch = palette[target]

Reactive Streams KTX

Reactive Streams KTX モジュールを使用すると、ReactiveStreams パブリッシャーから Observable 型の LiveData ストリームを作成できます。

このモジュールをインクルードするには、アプリの build.gradle ファイルに次の行を追加します。

    dependencies {
        implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:2.2.0"
    }
    

たとえば、ユーザー数が少ないデータベースがあるとします。アプリでは、データベースをメモリに読み込んでから UI にユーザーデータが表示されます。これを行うためには RxJava などが使用されます。Room Jetpack コンポーネントでは、ユーザーリストを Flowable として取得できます。このシナリオでは、フラグメントまたはアクティビティの全存続期間にわたって Rx パブリッシャーのサブスクリプションを管理する必要もあります。

ただし、LiveDataReactiveStreams では、LiveData のシンプルさを享受しつつ、RxJava とその演算子および作業スケジューリング機能の充実したセットも活用できます。

val fun getUsersLiveData() : LiveData<List<User>> {
    val users: Flowable<List<User>> = dao.findUsers()
    return LiveDataReactiveStreams.fromPublisher(users)
}

Room KTX

Room 拡張機能は、データベース トランザクション向けのコルーチン サポートを追加します。

このモジュールを使用するには、アプリの build.gradle ファイルに次の行を追加します。

    dependencies {
        implementation "androidx.room:room-ktx:2.2.5"
    }
    

以下に、Room でコルーチンを使用する例をいくつか示します。最初の例では、suspend 関数を使用して User オブジェクトのリストを返します。2 つ目の例では、Kotlin の Flow を利用して非同期で User リストを返します。なお、Flow を使用すると、クエリ対象のテーブル内の変更も通知されます。

@Query("SELECT * FROM Users")
suspend fun getUsers(): List<User>

@Query("SELECT * FROM Users")
fun getUsers(): Flow<List<User>>

SQLite KTX

SQLite 拡張機能は SQL 関連のコードをトランザクション内にラップします。これにより、多くのボイラープレート コードを省くことができます。

このモジュールを使用するには、アプリの build.gradle ファイルに次の行を追加します。

    dependencies {
        implementation "androidx.sqlite:sqlite-ktx:2.1.0"
    }
    

次の例では、transaction 拡張機能を使用してデータベース トランザクションを実行しています。

db.transaction {
    // insert data
}

ViewModel KTX

ViewModel KTX ライブラリでは、ViewModel からコルーチンを起動しやすくする viewModelScope() 関数が提供されています。CoroutineScopeDispatchers.Main にバインドされ、ViewModel が消去されると自動的にキャンセルされます。各 ViewModel に新しいスコープを作成するのではなく viewModelScope() を使用することが可能です。

このモジュールをインクルードするには、アプリの build.gradle ファイルに次の行を追加します。

    dependencies {
        implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
    }
    

たとえば、次の viewModelScope() 関数は、バックグラウンド スレッドでネットワーク リクエストを送信するコルーチンを起動します。ライブラリは、すべての設定および対応するスコープ消去を処理します。

class MainViewModel : ViewModel() {
    // Make a network request without blocking the UI thread
    private fun makeNetworkRequest() {
        // launch a coroutine in viewModelScope
        viewModelScope.launch  {
            remoteApi.slowFetch()
            ...
        }
    }

    // No need to override onCleared()
}

WorkManager KTX

WorkManager KTX は、最大級のコルーチン サポートを提供します。

このモジュールをインクルードするには、アプリの build.gradle ファイルに次の行を追加します。

    dependencies {
        implementation "androidx.work:work-runtime-ktx:2.3.4"
    }
    

Worker を拡張する代わりに、API が若干異なる CoroutineWorker を拡張できるようになりました。たとえば、シンプルな CoroutineWorker を構築してネットワーク オペレーションを実行するには、次のようにします。

class CoroutineDownloadWorker(context: Context, params: WorkerParameters)
        : CoroutineWorker(context, params) {

    override suspend fun doWork(): Result = coroutineScope {
        val jobs = (0 until 100).map {
            async {
                downloadSynchronously("https://www.google.com")
            }
        }

        // awaitAll will throw an exception if a download fails, which
        // CoroutineWorker will treat as a failure
        jobs.awaitAll()
        Result.success()
    }
}

CoroutineWorker の使用に関する詳細については、CoroutineWorker でのスレッド化をご覧ください。

WorkManager KTX では、現在のコルーチンを中断する Operations および ListenableFutures の拡張関数も追加されています。

次の例では、enqueue() によって返される Operation が中断されます。

// Inside of a coroutine...

// Run async operation and suspend until completed.
WorkManager.getInstance()
        .beginWith(longWorkRequest)
        .enqueue().await()

// Resume after work completes...

その他の KTX モジュール

AndroidX の外部に存在する追加の KTX モジュールもインクルードできます。

Firebase KTX

Android 向けの Firebase SDK の一部は Kotlin 拡張ライブラリを備えており、アプリで Firebase を使用する際に慣用的な Kotlin コードを記述できます。詳細については、次のトピックをご覧ください。

Play Core KTX

Play Core KTX では、Play Core ライブラリに SplitInstallManager および AppUpdateManager の拡張関数を追加することで、ワンショット リクエスト用 Kotlin コルーチンおよびステータス更新モニタリング用フローのサポートが追加されています。

このモジュールをインクルードするには、アプリの build.gradle ファイルに次の行を追加します。

dependencies {
    implementation "com.google.android.play:core-ktx:1.7.3"
}

Flow のステータス モニタリングの例を次に示します。

// Inside of a coroutine...

// Request in-app update status updates.
manager.requestUpdateFlow().collect { updateResult ->
    when (updateResult) {
        is AppUpdateResult.Available -> TODO()
        is AppUpdateResult.InProgress -> TODO()
        is AppUpdateResult.Downloaded -> TODO()
        AppUpdateResult.NotAvailable -> TODO()
    }
}

詳細

Android KTX の詳細については、DevBytes の動画をご覧ください。

問題を報告または機能を提案するには、Android KTX の Issue Tracker をご使用ください。