Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kotlin + RxJava2 + Dagger2 + Orma
+ Retrofit2 で...

Kotlin + RxJava2 + Dagger2 + Orma
+ Retrofit2 で作るAndroidアプリ at DroidKaigi 2017

TwitterID変えました。@lvla0805 -> @MoyuruAizawa

このスライド内ではHTTP通信にObservableを利用していますが、HTTP通信は成功か失敗しかないので本来であればSingleを利用するほうが妥当です。
このスライドでは敷居をさげるためにStreamの説明をObservableだけにとどめました。

Moyuru Aizawa

March 10, 2017
Tweet

More Decks by Moyuru Aizawa

Other Decks in Programming

Transcript

  1. Agenda ‣ Sample Application ‣ ٕज़֓ཁ ‣ Kotlin ‣ RxJava

    ‣ Retrofit ‣ Orma ‣ Sample ‣ Client ‣ Database ‣ Repository ‣ Activity ‣ Dagger2
  2. ٕज़֓ཁ Languages Kotlin 1.1 Network Retrofit 2.1.0 OkHttp 3.6.0 O/R

    Mapper Orma 4.2.0 Reactive Programming RxJava 2.0.2 Dependency Injection Dagger 2.9
  3. build.gradle(Ұ෦) apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' android { dataBinding

    { enabled = true } } dependencies { // Databinding kapt 'com.android.databinding:compiler:2.3.0' // Orma compile "com.github.gfx.android.orma:orma:$ormaVersion" kapt "com.github.gfx.android.orma:orma-processor:$ormaVersion" // ReactiveX compile 'io.reactivex.rxjava2:rxjava:2.0.2' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' // Retrofit compile "com.squareup.retrofit2:retrofit:$retrofitVersion" compile "com.squareup.retrofit2:converter-gson:$retrofitVersion" compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0' compile "com.squareup.okhttp3:logging-interceptor:$okHttpVersion" // Dagger2 compile "com.google.dagger:dagger:$daggerVersion" kapt "com.google.dagger:dagger-compiler:$daggerVersion" }
  4. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    … val message = "Clicked" button.setOnClickListener { textView.text = message } } } Kotlin
  5. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    … val message = "Clicked" button.setOnClickListener { textView.text = message } } } Kotlin
  6. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    … val message = "Clicked" button.setOnClickListener { textView.text = message } } } Kotlin
  7. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    … val message = "Clicked" button.setOnClickListener { textView.text = message } } } Kotlin
  8. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    … val message = "Clicked" button.setOnClickListener { textView.text = message } } } Kotlin
  9. class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {

    … val message = "Clicked" button.setOnClickListener { textView.text = message } } } Kotlin
  10. RxJava val observable = Observable.create<Int> { subscriber -> intArray.forEach {

    subscriber.onNext(it) } subscriber.onComplete() } observable.subscribe( { num -> println(num) }, { throwable -> throwable.printStackTrace() }, { println("onCompleted") })
  11. RxJava val observable = Observable.create<Int> { subscriber -> intArray.forEach {

    subscriber.onNext(it) } subscriber.onComplete() } observable.subscribe( { num -> println(num) }, { throwable -> throwable.printStackTrace() }, { println("onCompleted") })
  12. RxJava val observable = Observable.create<Int> { subscriber -> intArray.forEach {

    subscriber.onNext(it) } subscriber.onComplete() } observable.subscribe( { num -> println(num) }, { throwable -> throwable.printStackTrace() }, { println("onCompleted") })
  13. RxJava val observable = Observable.create<Int> { subscriber -> intArray.forEach {

    subscriber.onNext(it) } subscriber.onComplete() } observable.subscribe( { num -> println(num) }, { throwable -> throwable.printStackTrace() }, { println("onCompleted") })
  14. RxJava val observable = Observable.create<Int> { subscriber -> intArray.forEach {

    subscriber.onNext(it) } subscriber.onComplete() } observable.subscribe( { num -> println(num) }, { throwable -> throwable.printStackTrace() }, { println("onCompleted") })
  15. RxJava val observable = Observable.create<Int> { subscriber -> intArray.forEach {

    subscriber.onNext(it) } subscriber.onComplete() } observable.subscribe( { num -> println(num) }, { throwable -> throwable.printStackTrace() }, { println("onCompleted") })
  16. RxJava val observable = Observable.create<Int> { subscriber -> intArray.forEach {

    subscriber.onNext(it) } subscriber.onComplete() } observable.subscribe( { num -> println(num) }, { throwable -> throwable.printStackTrace() }, { println("onCompleted") })
  17. RxJava val observable = Observable.create<Int> { subscriber -> intArray.forEach {

    subscriber.onNext(it) } subscriber.onComplete() } observable.subscribe( { num -> println(num) }, { throwable -> throwable.printStackTrace() }, { println("onCompleted") })
  18. RxJava val observable = Observable.create<Int> { subscriber -> intArray.forEach {

    subscriber.onNext(it) } subscriber.onComplete() } observable.subscribe( { num -> println(num) }, { throwable -> throwable.printStackTrace() }, { println("onCompleted") })
  19. Orma @Table data class Contributor( @PrimaryKey(auto = false) @Setter("name") val

    name: String, @Column @Setter("avatarUrl") val avatarUrl: String?, @Column @Setter("htmlUrl") val htmlUrl: String?, @Column @Setter("contributions") val contributions: Int )
  20. Orma @Table data class Contributor( @PrimaryKey(auto = false) @Setter("name") val

    name: String, @Column @Setter("avatarUrl") val avatarUrl: String?, @Column @Setter("htmlUrl") val htmlUrl: String?, @Column @Setter("contributions") val contributions: Int )
  21. Orma @Table data class Contributor( @PrimaryKey(auto = false) @Setter("name") val

    name: String, @Column @Setter("avatarUrl") val avatarUrl: String?, @Column @Setter("htmlUrl") val htmlUrl: String?, @Column @Setter("contributions") val contributions: Int )
  22. Orma @Table data class Contributor( @PrimaryKey(auto = false) @Setter("name") val

    name: String, @Column @Setter("avatarUrl") val avatarUrl: String?, @Column @Setter("htmlUrl") val htmlUrl: String?, @Column @Setter("contributions") val contributions: Int )
  23. Dao

  24. Dao class ContributorDao(orma: OrmaDatabase) { fun insert(contributors: List<Contributor>) { orma.transactionSync

    { orma.prepareInsertIntoContributor(OnConflict.REPLACE) .executeAll(contributors) } } fun findAll(): List<Contributor> { return orma.selectFromContributor() .executeAsObservable() .toList() } }
  25. Dao class ContributorDao(orma: OrmaDatabase) { fun insert(contributors: List<Contributor>) { orma.transactionSync

    { orma.prepareInsertIntoContributor(OnConflict.REPLACE) .executeAll(contributors) } } fun findAll(): List<Contributor> { return orma.selectFromContributor() .executeAsObservable() .toList() } }
  26. Dao class ContributorDao(orma: OrmaDatabase) { fun insert(contributors: List<Contributor>) { orma.transactionSync

    { orma.prepareInsertIntoContributor(OnConflict.REPLACE) .executeAll(contributors) } } fun findAll(): List<Contributor> { return orma.selectFromContributor() .executeAsObservable() .toList() } }
  27. Repository class ContributorRepository( private val client: GitHubClient, private val dao:

    ContributorDao) { fun getContributors(): Observable<List<Contributor>> { return client.fetchContributors() .doOnNext { list -> dao.insert(list) } .onErrorReturn { dao.findAll() } } }
  28. Repository class ContributorRepository( private val client: GitHubClient, private val dao:

    ContributorDao) { fun getContributors(): Observable<List<Contributor>> { return client.fetchContributors() .doOnNext { list -> dao.insert(list) } .onErrorReturn { dao.findAll() } } }
  29. Repository class ContributorRepository( private val client: GitHubClient, private val dao:

    ContributorDao) { fun getContributors(): Observable<List<Contributor>> { return client.fetchContributors() .doOnNext { list -> dao.insert(list) } .onErrorReturn { dao.findAll() } } }
  30. Repository class ContributorRepository( private val client: GitHubClient, private val dao:

    ContributorDao) { fun getContributors(): Observable<List<Contributor>> { return client.fetchContributors() .doOnNext { list -> dao.insert(list) } .onErrorReturn { dao.findAll() } } }
  31. Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  32. Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  33. Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  34. Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  35. Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  36. Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  37. Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  38. Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  39. Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  40. Activity class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  41. Module @Module class ApplicationModule(private val applicationContext: App) { @Provides fun

    provideContext(): Context {…} @Provides fun provideOkHttp(): OkHttpClient {…} @Provides fun provideRetrofit(o: OkHttpClient): Retrofit {…} @Provides fun provideOrma(c: Context): OrmaHolder {…} @Provides fun provide…Dao(oh: OrmaHolder): ContributorDao {…} @Provides fun provideGitHubService(r: Retrofit): GitHubService {…} @Provides fun provideGitHubClient(s: GitHubService): GitHubClient {…} }
  42. Module @Module class ApplicationModule(private val applicationContext: App) { @Provides fun

    provideContext(): Context {…} @Provides fun provideOkHttp(): OkHttpClient {…} @Provides fun provideRetrofit(o: OkHttpClient): Retrofit {…} @Provides fun provideOrma(c: Context): OrmaHolder {…} @Provides fun provide…Dao(oh: OrmaHolder): ContributorDao {…} @Provides fun provideGitHubService(r: Retrofit): GitHubService {…} @Provides fun provideGitHubClient(s: GitHubService): GitHubClient {…} }
  43. Module @Module class ApplicationModule(private val applicationContext: App) { @Provides fun

    provideContext(): Context {…} @Provides fun provideOkHttp(): OkHttpClient {…} @Provides fun provideRetrofit(o: OkHttpClient): Retrofit {…} @Provides fun provideOrma(c: Context): OrmaHolder {…} @Provides fun provide…Dao(oh: OrmaHolder): ContributorDao {…} @Provides fun provideGitHubService(r: Retrofit): GitHubService {…} @Provides fun provideGitHubClient(s: GitHubService): GitHubClient {…} }
  44. Module @Module class ApplicationModule(private val applicationContext: App) { @Provides fun

    provideContext(): Context {…} @Provides fun provideOkHttp(): OkHttpClient {…} @Provides fun provideRetrofit(o: OkHttpClient): Retrofit {…} @Provides fun provideOrma(c: Context): OrmaHolder {…} @Provides fun provide…Dao(oh: OrmaHolder): ContributorDao {…} @Provides fun provideGitHubService(r: Retrofit): GitHubService {…} @Provides fun provideGitHubClient(s: GitHubService): GitHubClient {…} }
  45. TIPS @Module class ApplicationModule(private val applicationContext: App) { @Provides fun

    provideContext(): Context {…} @Provides fun provideOkHttp(): OkHttpClient {…} @Provides fun provideRetrofit(o: OkHttpClient): Retrofit {…} @Provides fun provideOrma(c: Context): OrmaHolder {…} @Provides fun provide…Dao(oh: OrmaHolder): ContributorDao {…} @Provides fun provideGitHubService(r: Retrofit): GitHubService {…} @Provides fun provideGitHubClient(s: GitHubService): GitHubClient {…} }
  46. Application class class App : Application() { lateinit var component:

    ApplicationComponent override fun onCreate() { component = DaggerApplicationComponent.builder() .applicationModule(ApplicationModule(this)) .build() } }
  47. Application class class App : Application() { lateinit var component:

    ApplicationComponent override fun onCreate() { component = DaggerApplicationComponent.builder() .applicationModule(ApplicationModule(this)) .build() } }
  48. Application class class App : Application() { lateinit var component:

    ApplicationComponent override fun onCreate() { component = DaggerApplicationComponent.builder() .applicationModule(ApplicationModule(this)) .build() } }
  49. Application class class App : Application() { lateinit var component:

    ApplicationComponent override fun onCreate() { component = DaggerApplicationComponent.builder() .applicationModule(ApplicationModule(this)) .build() } }
  50. Application class class App : Application() { lateinit var component:

    ApplicationComponent override fun onCreate() { component = DaggerApplicationComponent.builder() .applicationModule(ApplicationModule(this)) .build() } }
  51. Application class class App : Application() { lateinit var component:

    ApplicationComponent override fun onCreate() { component = DaggerApplicationComponent.builder() .applicationModule(ApplicationModule(this)) .build() } }
  52. Application class class App : Application() { val component: ApplicationComponent

    by lazy { DaggerApplicationComponent.builder() .applicationModule(ApplicationModule(this)) .build() } }
  53. MainActivity class MainActivity : AppCompatActivity() { @Inject lateinit var repository:

    ContributorRepository override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) (application as App).component.inject(this) repository.getContributors().... } }
  54. MainActivity class MainActivity : AppCompatActivity() { @Inject lateinit var repository:

    ContributorRepository override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) (application as App).component.inject(this) repository.getContributors().... } }
  55. MainActivity class MainActivity : AppCompatActivity() { @Inject lateinit var repository:

    ContributorRepository override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) (application as App).component.inject(this) repository.getContributors().... } }
  56. Before class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) val retrofit = Retrofit.Builder().......build() val orma = OrmaDatabase.builder(context).......build() val service = retrofit.create(GitHubService::class.java) val client = ContributorClient(service) val dao = ContributorDao(orma) val repository = ContributorRepository(client, dao) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }
  57. After class MainActivity : AppCompatActivity() { @Inject lateinit var repository:

    ContributorRepository override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) (application as App).component.inject(this) repository.getContributors() .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { contributors -> showContributors(contributors) }, { Timber.e(it, "getContributors") } ) } }