LoginSignup
2
3

More than 1 year has passed since last update.

[Android] Koinの使い方

Posted at

久しぶりにKoinを触ったので、メモメモ。

Koinを導入

まずKoinを導入します。

導入については こちら を参考にしました。

build.gradle
buildscript {
    // 追加
    ext.koin_version = '3.1.2'
    ext.kotlin_version = '1.5.20'
    repositories {
        google()
    // なければ追加する
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.0"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
app/build.gradle
dependencies {
    ...
    // 追加
    implementation "io.insert-koin:koin-android:$koin_version"
}

Setup Koin v3 に記載されていますが、jcenterの閉鎖で、koinプロジェクトのIDがorg.koinからio.insert-koinに変更されたとのことです。

Due to Jcenter shutdown, the koin project's maven group id was previously org.koin and is now io.insert-koin. Please check your configuration with modules below.

Applicationクラスで初期化する

アプリが起動するときに最初に呼び出されるApplicationを継承したクラスで、Koinの初期化を行います。

MyApp.kt
package com.example.sample

import android.app.Application
import org.koin.android.ext.koin.androidContext
import org.koin.core.context.startKoin

class MyApp : Application() {

    override fun onCreate() {
        super.onCreate()
        setupKoin()
    }

    private fun setupKoin() {

        startKoin {
            androidContext(this@MyApp)
            modules(modules)
        }
    }
}
AppModule.kt
package com.example.sample

import com.example.sample.model.repository.Repository
import com.example.sample.model.repository.RepositoryImpl
import com.example.sample.ui.MainViewModel
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module

val modules = module {
    // interfaceでDIしたいときは、ジェネリクスにinterface、{ } に継承したクラスを定義する。
    single<Repository> { RepositoryImpl() }
    viewModel { MainViewModel() }
    // AndroidViewModelを継承している場合、コンストラクタでApplicationが必要になるので「get()」を使う
    viewModel { SampleViewModel(get()) }
}

モジュール宣言を別ファイルに切り出しています。各宣言については以下のような動きになります。

  • single: シングルトンでモジュール宣言
  • factory: モジュール宣言したクラスが必要になるたび、インスタンスを生成する
  • viewModel: ViewModelのモジュール宣言で使用する
AndroidManifest.xml
<application
        android:name=".MyApp"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true">
        <activity
            android:name=".ui.MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

android:nameMyApp.ktを設定して、アプリ起動時に呼び出されるようにします。

DIする

実際にDIしてみます。

MainActivity.kt
class MainActivity : AppCompatActivity() {

    // MainViewModelをDIする
    private val _viewModel: MainViewModel by inject()

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

        ...
    }
}
MainViewModel.kt
class MainViewModel : ViewModel() {

    private val _repository: Repository by inject(Repository::class.java)

    init {
        fetchRepositories()
    }

    private fun fetchRepositories(userName: String = "user") {

        viewModelScope.launch(Dispatchers.IO) {
            val result = _repository.fetchRepositories(userName)
            ...
        }
    }
}
2
3
0

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
  3. You can use dark theme
What you can do with signing up
2
3