Slide 1

Slide 1 text

How to start dev Wasabeef GDG Tokyo New Year Party 2019 #gdgtokyo

Slide 2

Slide 2 text

About me Daichi Furiya Google Developers Expert CATS @wasabeef_jp wasabeef

Slide 3

Slide 3 text

今年から Android アプリを 作るなら知っておきたいこと January 2019

Slide 4

Slide 4 text

IDE (Build tools) Java / Kotlin Architecture Jetpack KTX AAC Agenda DI Networking Testing CI Multi-platform

Slide 5

Slide 5 text

IDE (Build tools)

Slide 6

Slide 6 text

Android Studio 3.3 Stable 3.4 BETA 3.5 Canary Gradle Bazel IDE (Build tools)

Slide 7

Slide 7 text

Android Studio

Slide 8

Slide 8 text

Android Studio 見た目はこんな感じ。DL→https://d.android.com/studio

Slide 9

Slide 9 text

Layout editor 直接XMLを書くこと多いですが、Layout Editorは高機能です

Slide 10

Slide 10 text

MotionLayout

Slide 11

Slide 11 text

Motion editor 今現在は実装されていませんが、Flash pro のようなエディタも実装される予定です

Slide 12

Slide 12 text

Motion editor 今現在は実装されていませんが、Flash pro のようなエディタも実装される予定です

Slide 13

Slide 13 text

Emulator 数年前と比べると格段に高機能で高速になりま した。 Quick-boot Snapshots ARCore Screen Record Wifi, Location, Camera, Battery
 … and more

Slide 14

Slide 14 text

Emulator では出来ないこと Bluetooth NFC Device-attached headphones USB

Slide 15

Slide 15 text

Performance monitor

Slide 16

Slide 16 text

Gradle

Slide 17

Slide 17 text

Gradle ビルド自動化 Android 開発におけるスタンダード DSL Groovy DSL ※ デフォルト Kotlin DSL

Slide 18

Slide 18 text

Java / Kotlin

Slide 19

Slide 19 text

Java / Kotlin Java Kotlin Dart

Slide 20

Slide 20 text

Java

Slide 21

Slide 21 text

Java Java 8 
 最新の Java は使えません
 ※ D8 tools によって今後変わりそう

Slide 22

Slide 22 text

Java 8 - Unsupported features and APIs Java 8 Language API Compatible minSdkVersion java.lang.annotation.Repeatable Android 7 (API24) + AnnotatedElement.getAnnotationsByType(Class) java.util.stream java.lang.FunctionalInterface java.lang.reflect.Method.isDefault() java.util.function

Slide 23

Slide 23 text

Kotlin

Slide 24

Slide 24 text

Kotlin Kotlin (1.3) Coroutines Null-safety Extension functions Lambda + Inline functions … and more

Slide 25

Slide 25 text

Architecture

Slide 26

Slide 26 text

Architecture MVVM Flux MVP MVI

Slide 27

Slide 27 text

MVVM

Slide 28

Slide 28 text

Google 推奨で AAC と相性が良い google/iosched nickbutcher/plaid MVVM

Slide 29

Slide 29 text

Flux

Slide 30

Slide 30 text

日本で数件の事例あり DroidKaigi/ conference-app-2019 Flux

Slide 31

Slide 31 text

Jetpack

Slide 32

Slide 32 text

Jetpack

Slide 33

Slide 33 text

Jetpack KTX Lifecycles ViewModel (+ LiveData) Navigation

Slide 34

Slide 34 text

KTX

Slide 35

Slide 35 text

KTX Core Fragment Lifecycle Navigation … and more

Slide 36

Slide 36 text

Samples view.viewTreeObserver.addOnPreDrawListener( object : ViewTreeObserver.OnPreDrawListener { override fun onPreDraw(): Boolean { viewTreeObserver.removeOnPreDrawListener(this) actionToBeTriggered() return true } } ) アニメーションの処理でよく見かけるコード

Slide 37

Slide 37 text

Samples view.doOnPreDraw { actionToBeTriggered() } かなりシンプルに出来ました

Slide 38

Slide 38 text

Lifecycles

Slide 39

Slide 39 text

Lifecycles 見えなくて 大丈夫です..

Slide 40

Slide 40 text

Lifecycles ライフサイクルを知りたい時がある 動画の開始停止 画面閉じた時の終了処理 … and more LiveData でも使われている

Slide 41

Slide 41 text

ViewModel (+ LiveData)

Slide 42

Slide 42 text

ViewModel Activity/ViewModel はそれぞれ異なるライ フサイクルがあります が、ViewModelのほ うが長生きします

Slide 43

Slide 43 text

ViewModel (+ LiveData) ViewModel Activity の画面回転・破棄のデータ保持 Fragments 間のデータ共有 永続化ではない LiveData Observable の一種

Slide 44

Slide 44 text

Samples class MyViewModel(private val repo: UserRepository) : ViewModel() { private val _user = MutableLiveData val user: LiveData get() = _user fun getUser() = return repo.getUser() } class MyActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { val model = ViewModelProviders.of(this).get(MyViewModel::class.java) model.getUser().observe(this, Observer { user -> // update UI }) } } よく見かける ViewModel + LiveData のサンプルです

Slide 45

Slide 45 text

class MyViewModel(private val repo: UserRepository) : ViewModel() { private val _user = MutableLiveData val user: LiveData get() = _user fun getUser() = return repo.getUser() } class MyActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { val model = ViewModelProviders.of(this).get(MyViewModel::class.java) model.getUser().observe(this, Observer { user -> // update UI }) } } Samples よく見かける ViewModel + LiveData のサンプルです

Slide 46

Slide 46 text

Navigation

Slide 47

Slide 47 text

Navigation Fragment Transaction の簡易化 アニメーション ディープリンク BottomNavigation / Toolbar などと連携 Fragment 間でデータを型安全に渡せる Navigation editor で GUI で設定可能

Slide 48

Slide 48 text

Navigation editor iOS の StoryBoard ぽいものが増えました。でもXML直接書く人のほうが多そう

Slide 49

Slide 49 text

Dependency Injection (DI)

Slide 50

Slide 50 text

Dependency Injection (DI) Dagger Koin Kodein

Slide 51

Slide 51 text

Dagger Java Google (+ Square) 少し難しいが一番利用されている Annotation Processing なので実行時は高速 Android Support

Slide 52

Slide 52 text

Koin Kotlin 軽量で簡単 ランタイム Daggerよりは実行時が遅い

Slide 53

Slide 53 text

Kodein Kotlin 簡単 ランタイム Daggerよりは実行時が遅い JVM, Android, JS, iOS でも動作する

Slide 54

Slide 54 text

Android Injection Performance Library Setup Kotlin Setup Java Inject Kotlin Inject Java Koin 19.80 ms 20.43 ms 0.45 ms 0.35 ms Kodein 21.48 ms 21.02 ms 0.74 ms 0.62 ms Dagger 0.03 ms 0.03 ms 0.22 ms 0.15 ms Sloy/android-dependency-injection-performance

Slide 55

Slide 55 text

Networking

Slide 56

Slide 56 text

Networking Retrofit (+ OkHttp) Ktor

Slide 57

Slide 57 text

Retrofit (+ OkHttp)

Slide 58

Slide 58 text

Retrofit (+ OkHttp) Square 社製 Android 5.0+ (OkHttp) JSON, Protobuf, XMLに対応 使いやすく、多くの人に使われている

Slide 59

Slide 59 text

interface SampleService { @GET("users/{user}") fun getUser(@Path("user") user: String): Deferred } val retrofit = Retrofit.Builder().baseUrl("https://wasabeef.jp/").client(okHttpClient).build() val service = retrofit.create(SampleService::class.java) launch { val user = service.getUser("wasabeef").await() // Do something } Samples よくあるサンプルコード

Slide 60

Slide 60 text

interface SampleService { @GET("users/{user}") fun getUser(@Path("user") user: String): Deferred } val retrofit = Retrofit.Builder().baseUrl("https://wasabeef.jp/").client(okHttpClient).build() val service = retrofit.create(SampleService::class.java) launch { val user = service.getUser("wasabeef").await() // Do something } Samples よくあるサンプルコード

Slide 61

Slide 61 text

interface SampleService { @GET("users/{user}") fun getUser(@Path("user") user: String): Deferred } val retrofit = Retrofit.Builder().baseUrl("https://wasabeef.jp/").client(okHttpClient).build() val service = retrofit.create(SampleService::class.java) launch { val user = service.getUser("wasabeef").await() // Do something } Samples よくあるサンプルコード

Slide 62

Slide 62 text

Testing

Slide 63

Slide 63 text

Testing Unit Test Firebase Test Lab

Slide 64

Slide 64 text

Unit Test

Slide 65

Slide 65 text

Unit Test 主なテスト方法は二つ Instrument Test
 実機やエミュレータ上でテスト行う Local Test (Robolectric)
 PC の JVM 上で擬似的にテストを行う

Slide 66

Slide 66 text

Unit Test Robolectric を使ったテストでは、実機 やエミュレータの無い CI 上でテストを 実行できる事や、それらを起動する必要 がないので、高速で行うことができる。
 ※ まれに JVM と Android(ArtVM)で挙動差があることがある

Slide 67

Slide 67 text

Firebase Test Lab

Slide 68

Slide 68 text

Firebase Test Lab .apk をアップロードするだけで実行が可能 Instrument/Robo Test の指定が可能 実機・エミュレータの指定ができる iOS も対応 ユーザ名・パスワードのログインにも対応 動作ログ (Screenshot, Video) が見れる

Slide 69

Slide 69 text

Firebase Test Lab コンソール画面

Slide 70

Slide 70 text

Firebase Test Lab Console で1件クラッシュしたことがわかる

Slide 71

Slide 71 text

Firebase Test Lab クラッシュ時のログも確認できる

Slide 72

Slide 72 text

Firebase Test Lab 実行時のスクリーンショットも確認できる

Slide 73

Slide 73 text

Firebase Test Lab どの時間、どの画面で負荷が上がったかがわかる

Slide 74

Slide 74 text

CI

Slide 75

Slide 75 text

CI bitrise CircleCI Danger

Slide 76

Slide 76 text

bitrise

Slide 77

Slide 77 text

bitrise モバイル向け GUI Firebase Test lab が無料で使える
 ※ 指定出来るデバイスは少なめ メモリ不足で落ちることは殆どない

Slide 78

Slide 78 text

bitrise CircleCI と比べるとデザインが良い

Slide 79

Slide 79 text

bitrise Console で1件クラッシュしたことがわかる

Slide 80

Slide 80 text

CircleCI

Slide 81

Slide 81 text

CircleCI 並列タスクが高機能
 Build, Lint, Test などを簡単に並列で出来る GUIがない (ので設定は慣れが必要) Android だとメモリ不足でよく落ちる
 ※ Performance pricing planに変更して、メモ リ量を増やすこともできる。

Slide 82

Slide 82 text

No content

Slide 83

Slide 83 text

Danger コードレビューの自動化をCI上で行う Android Lint, Swift Lint, ESLint, HLint, CheckStyle Format.......

Slide 84

Slide 84 text

Danger CI で Danger の連携をすると、Github コードレビューしてくれる

Slide 85

Slide 85 text

Multi-platform

Slide 86

Slide 86 text

Multi-platform Kotlin Multiplatform Flutter React Native

Slide 87

Slide 87 text

Kotlin Multiplatform

Slide 88

Slide 88 text

Kotlin Multiplatform iOS, macOS, Android, Windows, Linux, WASM に対応 サーバも Kotlin にして、Backends for Frontends の流れで使われることがある UIを作れるものでは無い

Slide 89

Slide 89 text

Kotlin Multiplatform iOS エンジニアにも Kotlin を読めるよう になってもらったほうが良い iOS は Coroutines が Single Thread で しか使えない https://aakira.app/blog/2018/12/kotlin-mpp-reason/

Slide 90

Slide 90 text

Flutter

Slide 91

Slide 91 text

Flutter Google Dart UI も作れる Android, iOS, (Web), (macOS), (Windows), (Linux), (Fuchsia) に対応

Slide 92

Slide 92 text

Fast development Hot-reload に対応しているので、画面開発、動作確認までが楽

Slide 93

Slide 93 text

Expressive, beautiful UIs Material Design のウィジットが豊富で画面を作りやすい

Slide 94

Slide 94 text

Native Performance Dart で書いたものが C/C++ でコンパイルされ、 iOS/Android にネイティブとして動く

Slide 95

Slide 95 text

Conclusion..

Slide 96

Slide 96 text

Conclusion.. 個人的な話 SingleActivity にして MVVM で良いと思います。
 AAC が MVVM 向きに作られてるような感じ。 Koin の実行速度が Dagger くらいにならないと導入はしない。
 理解が難しいけど、慣れればそこまでかな。 RxJava はもう使わなくてもいいかな。Kotlin (Coroutines), LiveData で十分。 Firebase Test Lab は絶対いれたい。 Arrow で Null-safety より安全なコードを目指したい。
 Scala属性でモナドの人は是非。 そういえば、DroidKaigi に Arrow のプロポーザル出したけど落ちた。 デスクトップアプリ作るなら Flutter にしたいな。

Slide 97

Slide 97 text

References: - https://d.android.com - https://kotlinlang.org - https://flutter.io - https://danger.systems - https://bitrise.io - https://circleci.com Resources Photos: - https://unsplash.com - https://www.pexels.com Illustrations: - http://www.chojugiga.com - https://www.irasutoya.com

Slide 98

Slide 98 text

twitter.com/wasabeef_jp wasabeef.jp github.com/wasabeef