11
8

More than 5 years have passed since last update.

Dagger2 + Retrofit2 + Moshi + Kotlin を使って通信するまで

Last updated at Posted at 2018-12-18

Kotlin を学ぶ際に、まずは通信周りを勉強したので、そこで得た知識を記事にしました。

Dagger2 + Retrofit2 + Moshi

Dagger2 + Retrofit2 + Moshi を導入する。

buildscript {
    ext.kotlin_version = '1.3.11'
    ext.dagger_version = '2.19'
    ext.retrofit_version = '2.5.0'
    ext.moshi_version = '1.8.0'
...
apply plugin: 'kotlin-kapt'
...
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
...
    implementation "com.google.dagger:dagger:$dagger_version"
    implementation "com.google.dagger:dagger-android:$dagger_version"
    implementation "com.google.dagger:dagger-android-support:$dagger_version"
    kapt "com.google.dagger:dagger-compiler:$dagger_version"
    kapt "com.google.dagger:dagger-android-processor:$dagger_version"
    implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
    implementation "com.squareup.retrofit2:converter-moshi:$retrofit_version"
    implementation "com.squareup.moshi:moshi:$moshi_version"
    implementation "com.squareup.moshi:moshi-kotlin:$moshi_version"

このままだと、ビルド時にエラーが発生するので、「jetifier-processor」を追加する。

    dependencies {
        classpath 'com.android.tools.build:gradle:3.2.1'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
...
        classpath 'com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta02'

Dagger2 を実装

Application - Component - 各 Module
の構成作る必要があるので、まず、Application と Component を作成する。

  • Component
import dagger.BindsInstance
import dagger.Component
import dagger.android.AndroidInjector
import dagger.android.support.AndroidSupportInjectionModule
import javax.inject.Singleton

@Singleton
@Component(modules = [AndroidSupportInjectionModule::class])
interface AppComponent : AndroidInjector<App> {
    override fun inject(application: App)

    @Component.Builder
    interface Builder {
        @BindsInstance
        fun application(application: App): Builder

        fun build(): AppComponent
    }
}
  • Application
import dagger.android.AndroidInjector
import dagger.android.support.DaggerApplication

class App : DaggerApplication() {
    override fun applicationInjector(): AndroidInjector<out DaggerApplication> {
        return DaggerAppComponent.builder().application(this).build()
    }
}
  • AndroidManifest
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:name=".App"

Activity を実装

Activity の Module を作成する。

@Module
abstract class ActivityModule {
    @ContributesAndroidInjector
    abstract fun contributeMainActivity(): MainActivity
}

Component にモジュールを追加する。

@Component(modules = [AndroidSupportInjectionModule::class, ActivityModule::class])
interface AppComponent : AndroidInjector<App> {
...

AppCompatActivity を DaggerAppCompatActivity に変更する。

class MainActivity : DaggerAppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
...

Retrofit2 + Moshi を実装

例として、GitHub のユーザ情報を取得する。

data class User(
    val name: String?,
    val company: String?,
    val email: String?,
    val bio: String?,
    val created_at: String?,
    val updated_at: String?
)

Retrofit2 の interface を作成する。

interface GitHubService {
    @GET("users/{username}")
    fun getUser(@Path("username") user: String): Call<User>
}

Retrofit2 の Module を作成する。

@Module
class RetrofitModule {
    @Provides
    @Singleton
    fun provideMoshi(): Moshi {
        return Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
    }

    @Provides
    @Singleton
    fun provideRetrofit(moshi: Moshi): Retrofit {
        return Retrofit.Builder()
            .baseUrl("https://api.github.com")
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .build()
    }

    @Provides
    @Singleton
    fun provideRetrofitService(retrofit: Retrofit): GitHubService = retrofit.create(GitHubService::class.java)
}

Component にモジュールを追加する。

@Component(modules = [AndroidSupportInjectionModule::class, ActivityModule::class, RetrofitModule::class])
interface AppComponent : AndroidInjector<App> {
...

依存性の注入をする。

class MainActivity : DaggerAppCompatActivity() {
    @Inject
    lateinit var github: GitHubService

GitHub のユーザ情報を取得する。

    override fun onResume() {
        super.onResume()

        val userCall: Call<User> = github.getUser("xxxxx")
        userCall.enqueue(object : Callback<User> {
            override fun onFailure(call: Call<User>, t: Throwable) {

            }

            override fun onResponse(call: Call<User>, response: Response<User>) {
                if (response.isSuccessful) {
                    val user: User? = response.body()
                }
            }
        })
    }

ここまでで、Dagger2 + Retrofit2 + Moshi + Kotlin を使って通信するまでを記載しました。
本来は、シングルトンや依存関係など色々考慮して実装する必要がありますが、Dagger2 を使用することで、Module を追加し、Inject するだけで、シングルトンや依存関係などを考慮する必要がなくなります。

11
8
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
11
8