LoginSignup
7
10

More than 1 year has passed since last update.

Android HiltをNew projectから最速セットアップ(2021/07)

Last updated at Posted at 2021-07-01

はじめに

この記事は、developer.android.comのHilt を使用した依存関係の注入を参照してのセットアップになります。
developer.android.comの内容は古いので、daggerの公式も参照してください。

概要

AndroidでHiltを使おうと、Hilt を使用した依存関係の注入 を参照したら、ドキュメントが古いためエラいハマったので、New Project→Basic Activityから最速でHiltをセットアップするための手順書になります。

特に言及のないところは公式ドキュメント通りで大丈夫かと思います。

環境

  • Android Studio
    • 4.2.2
  • 言語
    • Kotlin

依存関係を追加する

classpath 'com.google.dagger:hilt-android-gradle-plugin:2.28-alpha'ではなく、classpath 'com.google.dagger:hilt-android-gradle-plugin:2.37' を追加します。

kotlin_versionも、1.5.20にすると以下のようなエラーに悩まされるので、1.5.10にします。

public final class MainActivity extends androidx.appcompat.app.AppCompatActivity {
             ^
  Expected @AndroidEntryPoint to have a value. Did you forget to apply the Gradle Plugin? (dagger.hilt.android.plugin)
  See https://dagger.dev/hilt/gradle-setup.html
  [Hilt] Processing did not complete. See error above for details.

プロジェクトのルート build.gradle ファイル

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.5.10"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:4.2.2"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        classpath 'com.google.dagger:hilt-android-gradle-plugin:2.37'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

app/build.gradle ファイルも、com.google.daggerの各種バージョンを2.37にして追加します。
プラグインの書き方はapplyではなくpluginsに列挙する形になっているので、その形式に合わせます。

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
    id 'dagger.hilt.android.plugin'
}

dependencies {
    // Hilt
    implementation "com.google.dagger:hilt-android:2.37"
    kapt "com.google.dagger:hilt-android-compiler:2.37"
}

Hilt アプリケーション クラス

New→Kotlin Class/Fileでファイルを追加します。

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class ExampleApplication: Application() {
}

AndroidManifest.xmlにもapplication要素にandroid:nameを追加するように編集します。

    <application
        android:name=".ExampleApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplicationHilt">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.MyApplicationHilt.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

Android クラスに依存関係を注入する

公式ドキュメントでは、ExampleActivityを作成していますが、以下は最初からあるMainActivityに実装する例です。

import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    @Inject lateinit var analytics: AnalyticsAdapter

Hilt バインディングを定義する

New→Kotlin Class/FileでAnalyticsAdapterファイルを追加します。

import javax.inject.Inject

class AnalyticsAdapter @Inject constructor(
    private val service: AnalyticsService
) {
}

Hilt モジュール

@Binds を使用してインターフェース インスタンスを注入する

New→Kotlin Class/FileでAnalyticsServiceファイルを追加します。

import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.android.components.ActivityComponent
import javax.inject.Inject

interface AnalyticsService {
    fun analyticsMethods()
}

// Constructor-injected, because Hilt needs to know how to
// provide instances of AnalyticsServiceImpl, too.
class AnalyticsServiceImpl @Inject constructor(
) : AnalyticsService {
    override fun analyticsMethods() {
        TODO("Not yet implemented")
    }
}

@Module
@InstallIn(ActivityComponent::class)
abstract class AnalyticsModule {

    @Binds
    abstract fun bindAnalyticsService(
        analyticsServiceImpl: AnalyticsServiceImpl
    ): AnalyticsService
}

以上でビルドが通り、MainActivityからAnalyticsAdapterとAnalyticsServiceが利用できるようになるかと思います。

Hilt と Jetpack の統合(ViewModel & Fragment)

Hilt と Jetpack の統合もドキュメントが古いので、こちらも2021/07現在の環境でセットアップします。
以下はFragmentに対してのViewModelでのセットアップになります。

Hilt を使用して ViewModel オブジェクトを注入する

まずは、New→Fragment→Fragment (With ViewModel)で ExampleFragmentを作っておきます。
app/build.gradleファイルは、

  • implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha01'implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
  • kapt 'androidx.hilt:hilt-compiler:1.0.0-alpha01'kapt 'androidx.hilt:hilt-compiler:1.0.0'

にします。

dependencies {
    implementation 'androidx.hilt:hilt-lifecycle-viewmodel:1.0.0-alpha03'
    // When using Kotlin.
    kapt 'androidx.hilt:hilt-compiler:1.0.0'
}

ViewModelInjectはHiltViewModelに置き換えられているので、置き換えます。
ExampleRepositoryがconstructorに必要なので用意しておきます。
ExampleRepositoryの中身の例です。

import javax.inject.Inject

class ExampleRepository @Inject constructor() {
    fun get(): String {
        return "get"
    }
}

ViewModelの例です。

@HiltViewModel
class ExampleViewModel @Inject constructor(
    private val repository: ExampleRepository,
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {
    private val _text = MutableLiveData<String>().apply {
        value = repository.get()
    }
    val text: LiveData<String> = _text
}

そのViewModelを使うFragmentの例です。

import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class ExampleFragment : Fragment() {

    companion object {
        fun newInstance() = ExampleFragment()
    }

    private val viewModel: ExampleViewModel by viewModels()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        viewModel.text.observe(viewLifecycleOwner, Observer {
            Log.d("ExampleFragment",it)
        })
        return inflater.inflate(R.layout.example_fragment, container, false)
    }
}

以上、駆け足ですが、2021/07時点でのAndroid Hiltセットアップの例でした。

7
10
2

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
7
10