Slide 1

Slide 1 text

来年に備えるために Android の知識を網羅する Daichi Furiya / Wasabeef

Slide 2

Slide 2 text

Daichi Furiya(降矢 大地) Google Developers Expert CATS, CyberAgent @wasabeef_jp wasabeef

Slide 3

Slide 3 text

来年に備えるために Android の知識を網羅する

Slide 4

Slide 4 text

黎明期の Android アプリ開発は...

Slide 5

Slide 5 text

RetroLambda MVC VOLLEY JUICE ActionBarSherlock Timber

Slide 6

Slide 6 text

成熟期の Android アプリ開発は...

Slide 7

Slide 7 text

DAGGER2 MVVM FLUX MVI Timber

Slide 8

Slide 8 text

activity ads annotation appcompat arch asynclayoutinflater autofill benchmark biometric browser Jetpack に含まれるライブラリを並べてみると…

Slide 9

Slide 9 text

camera car cardview collection concurrent constraintlayout contentpager coordinatorlayout core cursoradapter Jetpack に含まれるライブラリを並べてみると…

Slide 10

Slide 10 text

customview databinding documentfile drawerlayout dynamicanimation emoji enterprise exifinterface fragment gridlayout Jetpack に含まれるライブラリを並べてみると…

Slide 11

Slide 11 text

heifwriter interpolator jetifier leanback legacy lifecycle loader localbroadcastmanager media media2 Jetpack に含まれるライブラリを並べてみると…

Slide 12

Slide 12 text

mediarouter multidex navigation paging palette percentlayout preference print recommendation recyclerview Jetpack に含まれるライブラリを並べてみると…

Slide 13

Slide 13 text

remotecallback room savedstate security sharetarget slice slidingpanelayout sqlite swiperefreshlayout test Jetpack に含まれるライブラリを並べてみると…

Slide 14

Slide 14 text

textclassifier transition tvprovider vectordrawable versionedparcelable viewpager viewpager2 wear webkit work Jetpack に含まれるライブラリを並べてみると…

Slide 15

Slide 15 text

activity ads annotation appcompat arch asynclayoutinflater autofill benchmark biometric browser camera car cardview collection concurrent constraintlayout contentpager coordinatorlayou core cursoradapter customview databinding documentfile drawerlayout dynamicanima emoji enterprise exifinterface fragment gridlayout heifwriter interpolator jetifier leanback legacy lifecycle loader localbroadcastmanager media media2 remotecallback room savedstate security sharetarget slice slidingpanelayout sqlite swiperefreshlayout textclassifier transition tvprovider vectordrawable versionedparcelable viewpager viewpager2 wear webkit work mediarouter multidex navigation paging palette percentlayout preference print recommendation recyclerview

Slide 16

Slide 16 text

activity ads annotation appcompat arch asynclayoutinflater autofill benchmark biometric browser camera car cardview collection concurrent constraintlayout contentpager coordinatorlayout core cursoradapter customview databinding documentfile drawerlayout dynamicanimation emoji enterprise exifinterface fragment gridlayout heifwriter interpolator jetifier leanback legacy lifecycle loader localbroadcastmanager media media2 mediarouter multidex navigation paging palette percentlayout preference print recommendation recyclerview remotecallback room savedstate security sharetarget slice slidingpanelayout sqlite swiperefreshlayout test textclassifier transition tvprovider vectordrawable versionedparcelable viewpager viewpager2 wear webkit work

Slide 17

Slide 17 text

activity ads annotation appcompat arch asynclayoutinflater autofill benchmark biometric browser camera car cardview collection concurrent constraintlayout contentpager coordinatorlayout core cursoradapter customview databinding documentfile drawerlayout dynamicanimation emoji enterprise exifinterface fragment gridlayout heifwriter interpolator jetifier leanback legacy lifecycle loader localbroadcastmanager media media2 mediarouter multidex navigation paging palette percentlayout preference print recommendation recyclerview remotecallback room savedstate security sharetarget slice slidingpanelayout sqlite swiperefreshlayout test textclassifier transition tvprovider vectordrawable versionedparcelable viewpager viewpager2 wear webkit work 70+ 個のライブラリ群

Slide 18

Slide 18 text

DAGGER2 MVVM FLUX MVI Timber activity ads annotation appcompat arch asynclayoutinflater autofill benchmark biometric browser camera car cardview collection concurrent constraintlayout contentpager coordinatorlayout core cursoradapter customview databinding documentfile drawerlayout dynamicanimation emoji enterprise exifinterface fragment gridlayout heifwriter interpolator jetifier leanback legacy lifecycle loader localbroadcastmanager media media2 mediarouter multidex navigation paging palette percentlayout preference print recommendation recyclerview remotecallback room savedstate security sharetarget slice slidingpanelayout sqlite swiperefreshlayout test textclassifier transition tvprovider vectordrawable versionedparcelable viewpager viewpager2 wear webkit work 70+ 個のライブラリ群

Slide 19

Slide 19 text

この場で話す範囲 Android 10 Android Studio 4.0 (Flutter) Kotlin (DSL, MPP, Coroutine, Flow) Architecture(MVVM) Jetpack (AAC, Compose) Networking (Retrofit+OkHttp) DI (Dagger2) Firebase (Test Lab)

Slide 20

Slide 20 text

Android 10

Slide 21

Slide 21 text

Security Updates Smart Reply Dark Theme Privacy Controls Family Link Live Caption Sound Amplifier Location Controls Gesture Navigation Focus Mode Android 10 Highlights

Slide 22

Slide 22 text

Location Controls

Slide 23

Slide 23 text

Location Controls バックグラウンドでロケーション 情報を取得するには、また別に権 限を取得しないといけません。

Slide 24

Slide 24 text

Gestural Navigation

Slide 25

Slide 25 text

Gestural Navigation これらをテーマから透過にする必要 があります。 ・ NavigationBar ・ StatusBar

Slide 26

Slide 26 text

Foldable

Slide 27

Slide 27 text

https://youtu.be/7r_UgNcJtzQ

Slide 28

Slide 28 text

アプリの継続性 まだ日本で購入できる端末は少な くて、シェアは多くないですが、 画面を折り畳んだ後も正常に実行 できるように考慮しなければいけ ません。

Slide 29

Slide 29 text

マルチウィンドウ そしてまた、画面を分割して、ア プリを複数立ち上げられるという ことは画面比率が変わることがあ るので、レイアウトが崩れないよ うに実装を注意する必要がありま す。

Slide 30

Slide 30 text

マルチウィンドウ レイアウト崩れもそうですが、も う一つ大きな注意点があります。 例えば YouTube を起動している ときに、Netflix を起動した場合 は、両方とも動画が流れ続けては いけません。

Slide 31

Slide 31 text

Android Studio 4.0

Slide 32

Slide 32 text

Motion Editor Jetpack Compose Multi-Preview Kotlin DSL Build Speed Emulator Multi-Display Google Map Integration Proguard Editing Desugaring in D8 & R8 Live Layout Inspector Android Studio 4.0 Highlights

Slide 33

Slide 33 text

Motion Editor

Slide 34

Slide 34 text

Motion Editor MotionLayout と Motion Editor を使うことで、GUI 上で簡単にアニメーション を実装できます。

Slide 35

Slide 35 text

Motion Editor MotionLayout と Motion Editor を使うことで、GUI 上で簡単にアニメーション を実装できます。

Slide 36

Slide 36 text

Motion Editor MotionLayout と Motion Editor を使うことで、GUI 上で簡単にアニメーション を実装できます。

Slide 37

Slide 37 text

Multi Preview

Slide 38

Slide 38 text

Multi Preview さまざまな解像度のデバイ スや、各国の言語設定をプ レビューすることができ、 これにより事前にレイアウ ト崩れなどをチェックでき ます。

Slide 39

Slide 39 text

Live Layout Inspector

Slide 40

Slide 40 text

Live Layout Inspector エミュレータなどでデバッ グしているアプリの View 構造を 3D に視覚化でき、 設定されているプロパティ 値などの確認を迅速に行え るようになります。

Slide 41

Slide 41 text

Flutter

Slide 42

Slide 42 text

Flutter 一つのソースコードからモバイル、 Web、デスクトップ向けにネイティブ コンパイルするための Google 製 UI ツールキットです。 国内の採用事例もいくつかあります。

Slide 43

Slide 43 text

Flutter の事をもっと知りたい方は.. Flutter Overview 17:00 〜 17:40 B202 上田 哲広 / Tetsuhiro Ueda

Slide 44

Slide 44 text

Kotlin

Slide 45

Slide 45 text

Kotlin 1.3.61 (2019.12.14)

Slide 46

Slide 46 text

2017年 Kotlin 公式言語化 2018年 Android Jetpack 発表 2019年 Kotlin-first

Slide 47

Slide 47 text

Kotlin-first? Java Kotlin Platform SDK support Yes Yes Android Studio support Yes Yes Lint Yes Yes Guided docs support Yes Yes API docs support Yes Yes AndroidX support Yes Yes AndroidX Kotlin-specific APIs (e.g. KTX, coroutines) N/A Yes Online training Best effort Yes Samples Best effort Yes Multi-platform Projects No Yes Jetpack Compose No Yes

Slide 48

Slide 48 text

60% のアプリで利用(TOP 1000) Kotlin-first?

Slide 49

Slide 49 text

Kotlin vs Java?

Slide 50

Slide 50 text

public final class Dog { private String name; private Color color; private LocalDate birthday; private float height; private float weight; public String getName() { return name; } public void setName(String name) { this.name = name; } public Color getColor() { return color; } Kotlin data class Dog( var name: String, var color: Color, var birthday: LocalDate, var height: Float, var weight: Float ) Java

Slide 51

Slide 51 text

Android Java にはない Kotlin の機能 SAM 変換 拡張関数 データクラス Null-safety インライン関数 スマートキャスト Coroutines Flows etc..

Slide 52

Slide 52 text

Kotlin Coroutines

Slide 53

Slide 53 text

Android Threading Android マルチスレッドにおいての画面の更新はメインス レッドで実行する必要があり、API 通信などはメインスレッ ドで通信してはいけません。 また、Activity や Fragment が破棄された後にそれらのス レッドをキャンセルするためにライフサイクルを知っておく 必要もあります。

Slide 54

Slide 54 text

java.lang.Thread, android.os.Handler(API Level 1) もっとも古くからある原始的 な非同期処理で、Activity などのライフサイクルは考慮 されていません。Thread, Handler はあらゆる非同期 処理の内部実装で使われてい ます。 Thread { val bitmap = loadBitmap("https: //wasabeef.jp/image.png") Handler(mainLooper).post { imageView.setImageBitmap(bitmap) } }.start()

Slide 55

Slide 55 text

RxJava 非同期処理用ではなくリア クティブプログラミングの ライブラリです。ライフサ イクルに紐づけることもで きます。RxJava の機能全 体を把握するのは難しく、 学習コストが高めです。 val observable = Observable.create { emitter -> val bitmap = loadBitmap("https: //wasabeef.jp/image.png") emitter.onNext(bitmap) emitter.onComplete() }.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( { bitmap -> imageView.setImageBitmap(bitmap) }, { error -> /** do something **/ }) .addTo(compositeDisposable) }

Slide 56

Slide 56 text

Kotlin Coroutines 軽量スレッド キャンセルが簡単 失敗時のハンドリングが簡単 ライフサイクルへの紐付けが簡単 2019年が移行期 1.3.3

Slide 57

Slide 57 text

コルーチンビルダーで す。launch 関数を呼び 出すことでコルーチンが 開始されます。 launch { println("Hello, Coroutines !!") } launch - Kotlin Coroutines

Slide 58

Slide 58 text

val job = launch { println("Hello, Coroutines !!") } job.cancel() また、launch 関数は Job クラスを返します。この Job はコルーチンのライフ サイクルのハンドリングを 提供します。アクティブ状 態か完了しているかなどを 把握でき、キャンセルする こともできます。 Job - Kotlin Coroutines

Slide 59

Slide 59 text

Job では Job 同士を階 層関係で管理することが できます。launch 関数 を呼ぶときに親にあた る Job を渡すことでそ れが可能となります。 val parentJob = Job() val job = launch(parentJob) { println("Hello, Coroutines !!") } parentJob.cancel() Job hierarchy - Kotlin Coroutines

Slide 60

Slide 60 text

Job の階層関係を作るこ とで、親 Job をキャン セルした場合には、子 Job もキャンセルするこ とができます。 Job hierarchy - Kotlin Coroutines Parent Job Child Job A Child Job B Child Job C .cancel() .cancel() .cancel() .cancel()

Slide 61

Slide 61 text

Job によってコルーチ ンのライフサイクルを ハンドリングすること ができますが、そのコ ルーチンは、どういう スコープで生存させる かを決めることができ ます。 CotoutineScope - Kotlin Coroutines val parentJob = Job() val job = launch(parentJob) { println("Hello, Coroutines !!") } parentJob.cancel()

Slide 62

Slide 62 text

val scope = CoroutineScope(Job()) val job = scope.launch { println("Hello, Coroutines !!") } scope.cancel() launch 関数は全て CoroutineScope の中で 実行されます。これまで 省略していましたが、本 来はこのような形になっ ており。そのスコープ内 のコルーチンはキャンセ ルすることができます。 CotoutineScope - Kotlin Coroutines

Slide 63

Slide 63 text

このスコープを Activity、Fragment や ViewModel に合わせ ることで、Android のラ イフサイクルに紐づける ことができます。 CotoutineScope - Kotlin Coroutines val scope = CoroutineScope(Job()) val job = scope.launch { println("Hello, Coroutines !!") } scope.cancel()

Slide 64

Slide 64 text

launch 関数にはコルー チンが実行に使用するス レッドを指定することが できます。CPU に負荷 がかかるような計算など はメインスレッドではな く Default を使用する ことができます。 CotoutineDispatcher - Kotlin Coroutines val scope = CoroutineScope(Job()) val job = scope.launch(Dispatchers.Default) { println("Hello, Coroutines !!") } scope.cancel()

Slide 65

Slide 65 text

val scope = CoroutineScope(Job()) val job = scope.launch(Dispatchers.Main) { println("Hello, Coroutines !!") } scope.cancel() Android において画面 の更新はメインスレッド で行わないといけないた め、Main を指定するこ とにより UI 操作もする こができます。 CotoutineDispatcher - Kotlin Coroutines

Slide 66

Slide 66 text

val scope = CoroutineScope(Job()) val job = scope.launch(Dispatchers.IO) { println("Hello, Coroutines !!") } scope.cancel() メインスレッドではな く、データベース、ファ イルの読み書きやネット ワーク通信をする場合に は IO を指定することで パフォーマンスも期待で きます。 CotoutineDispatcher - Kotlin Coroutines

Slide 67

Slide 67 text

CoroutineScope を生 成するときに、スコープ のデフォルトスレッドを 指定したい場合などに は、+ でつなげること ができます。 val scope = CoroutineScope(Job() + Dispatchers.IO) val job = scope.launch { println("Hello, Coroutines !!") } scope.cancel() CotoutineDispatcher - Kotlin Coroutines

Slide 68

Slide 68 text

Kotlin Flows

Slide 69

Slide 69 text

Kotlin Flows RxJava と同様に Reactive streams specification Coroutines は One-shotで、Flows は Observers として使う RxJava に比べたらやれることが少ない RxJava よりもパフォーマンス向上のためシンプルな設計 受信するまで動作しない(コールドストリーム) 2020年が移行期??

Slide 70

Slide 70 text

簡単に使ってみるのは とてもシンプルで、 flow {} ビルダーで生 成して、launch 内で collect 関数を呼ぶこ とで、emit された データを受信します。 Kotlin Flows val my Flow = flow { emit("Hello, World!") emit("I'm Flow?") } launch { my Flow.collect { data -> println(data) } }

Slide 71

Slide 71 text

Flow はコールドスト リームなので、collect 関数を何度呼んでも同じ データを受信します。 ホットストリームを使い たい場合は RxJava か Kotlin Channels を調 べてみましょう。 Kotlin Flows val my Flow = flow { emit("Hello, World!") emit("I'm Flow?") } launch { my Flow.collect { data -> println(data) } my Flow.collect { data -> println(data) } }

Slide 72

Slide 72 text

Kotlin/Native

Slide 73

Slide 73 text

Kotlin/Native Kotlin をネイティブバイナ リにコンパイルするための 技術であり、iOS などの仮 想マシンがない環境でも実 行できます。

Slide 74

Slide 74 text

Target Platforms - Kotlin/Native iOS (arm32, arm64, simulator x86_64) macOS (x86_64) Android (arm32, arm64) Windows (mingw x86_64, x86) Linux (x86_64, arm32, MIPS, MIPS LE, Raspberry Pi) WebAssembly (x86_64)

Slide 75

Slide 75 text

Kotlin Multiplatform

Slide 76

Slide 76 text

Kotlin Multiplatform KotlinConf 2019 でも多く のセッションがありました が、iOS と Android でビジ ネスロジックを Kotlin で共 通化するなどの事例が出始 めています。 ※ iOS の UI が作れるものではありません。 Kotlin/LLVM Kotlin/JVM Kotlin/JVM Kotlin/JS Common code

Slide 77

Slide 77 text

Architecture (MVVM)

Slide 78

Slide 78 text

Architecture(MVVM) Activity/Fragment Repository ViewModel LiveData Local Source Room Remote Data Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide 最近では Google の推奨 アーキテクチャとして MVVM が取り上げられて います。FLUX や MVI に 寄せて開発しているプロダ クトの事例もあります。

Slide 79

Slide 79 text

Architecture(MVVM) Activity/Fragment Repository ViewModel LiveData Local Source Room Remote Data Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide Jetpack そして、MVVM で設計す る上で、使いやすいライブ ラリが Jetpack には多く 存在します。

Slide 80

Slide 80 text

Architecture(MVVM) Activity/Fragment Repository ViewModel LiveData Local Source Room Remote Data Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide Jetpack そして、MVVM で設計す る上で、使いやすいライブ ラリが Jetpack には多く 存在します。

Slide 81

Slide 81 text

Architecture(MVVM) Activity/Fragment Repository ViewModel LiveData Local Source Room Remote Data Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide Jetpack そして、MVVM で設計す る上で、使いやすいライブ ラリが Jetpack には多く 存在します。

Slide 82

Slide 82 text

Architecture(MVVM) Activity/Fragment Repository ViewModel LiveData Local Source Room Remote Data Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide Jetpack そして、MVVM で設計す る上で、使いやすいライブ ラリが Jetpack には多く 存在します。 Jetpack Jetpack

Slide 83

Slide 83 text

Jetpack

Slide 84

Slide 84 text

activity ads annotation appcompat arch asynclayoutinflater autofill benchmark biometric browser camera car cardview collection concurrent constraintlayout contentpager coordinatorlayout core cursoradapter customview databinding documentfile drawerlayout dynamicanimation emoji enterprise exifinterface fragment gridlayout heifwriter interpolator jetifier leanback legacy lifecycle loader localbroadcastmanager media media2 mediarouter multidex navigation paging palette percentlayout preference print recommendation recyclerview remotecallback room savedstate security sharetarget slice slidingpanelayout sqlite swiperefreshlayout test textclassifier transition tvprovider vectordrawable versionedparcelable viewpager viewpager2 wear webkit work 70+ 個のライブラリ群

Slide 85

Slide 85 text

Architecture UI Behavior Foundation Jetpack ボイラープレートコードの 手間省けて、下位互換性を 備えたアプリを簡単に作成 するためのライブラリで す。androidx.* パッケー ジで構成されています。

Slide 86

Slide 86 text

Architecture UI Behavior Foundation Jetpack Data Binding Lifecycles LiveData Navigation Paging Room ViewModel WorkManager

Slide 87

Slide 87 text

Architecture UI Behavior Foundation Jetpack Animation & Transitions Auto, TV & Wear Emoji Fragment Layout Pallets

Slide 88

Slide 88 text

Architecture UI Behavior Foundation Jetpack Download Manager Media & Playback Permissions Notifications Sharing Slices

Slide 89

Slide 89 text

Architecture UI Behavior Foundation Jetpack AppCompat Android KTX Multidex Test

Slide 90

Slide 90 text

AppCompat ※ JetpackͷҰ෦

Slide 91

Slide 91 text

AppCompat 必ず使うことになるライブラ リで Android アプリ開発で は、古い OS の対応などがと ても困難でありそれらの問題 を吸収してくれるサポートラ イブラリとなります。 import androidx.appcompat.app.AppCompatActivity public class AppCompatActivity extends FragmentActivity implements ... { }

Slide 92

Slide 92 text

Android KTX ※ JetpackͷҰ෦

Slide 93

Slide 93 text

Android KTX Jetpack に含まれる Kotlin の拡張機能セッ ト。コードをシンプルにす ることができます。 view.viewTreeObserver.addOnPreDrawListener( object : ViewTreeObserver.OnPreDrawListener { override fun onPreDraw(): Boolean { viewTreeObserver.removeOnPreDrawListener(this) something() return true } } )

Slide 94

Slide 94 text

Android KTX Jetpack に含まれる Kotlin の拡張機能セッ ト。コードをシンプルにす ることができます。 view.doOnPreDraw { something() }

Slide 95

Slide 95 text

Android Architecture Components (AAC) ※ JetpackͷҰ෦

Slide 96

Slide 96 text

Android Architecture Components(AAC) Activity/Fragment Repository ViewModel LiveData Local Source Room Remote Data Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide AAC Android アーキテクチャ コ ンポーネントは、堅牢でテ ストとメンテナンスが簡単 なアプリの設計を支援する ライブラリのコレクション です。 Lifecycle, ViewModel, LiveData, Room... AAC AAC

Slide 97

Slide 97 text

Lifecycle ※ AACͷҰ෦

Slide 98

Slide 98 text

Android のライフサイク ルを理解するのも取り扱う のもとても大変です。多く の初学者が最初にぶつかる 壁かもしれません。 Lifecycle

Slide 99

Slide 99 text

Lifecycle Repository Local Source Room Remote Data Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide Android の UI コンポーネン トの多くがライフサイクルに 紐づいて作られています。そ のため Lifecycle ライブラリ では、そのライフサイクルに 簡単に対応できるように用意 されています。 Activity/Fragment ViewModel LiveData

Slide 100

Slide 100 text

Navigation ※ AACͷҰ෦

Slide 101

Slide 101 text

Navigation Repository ViewModel LiveData Local Source Room Remote Data Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide 単純なボタンクリックか ら、アプリバーやナビゲー ションドロワーなどの複雑 なパターンまで、さまざま なコンテンツ間を移動する を実装するに便利です。 Activity/Fragment

Slide 102

Slide 102 text

Navigation Android Studio にあるで きるナビゲーションエディ ターを使うことで、画面間 の遷移を視覚的に実装でき ます。

Slide 103

Slide 103 text

ナビゲーションエディター で設定することもできます が、それらは全て XML で 定義されています。なので もちろん直接編集すること ができますし、直接編集し て XML を整理したりする こともあります。 Navigation

Slide 104

Slide 104 text

Navigation 画面間のデータを型安全に渡せる Bottom Navigation の画面遷移にも対応 デープリンクの実装

Slide 105

Slide 105 text

ViewModel + LiveData ※ AACͷҰ෦

Slide 106

Slide 106 text

ViewModel + LiveData Activity/Fragment Repository Local Source Room Remote Data Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide これらを使うことによりライ フサイクルを意識した方法 で UI 関連のデータを保存お よび管理できます。 ViewModel LiveData

Slide 107

Slide 107 text

アプリの画面回転時に破棄 されないようデータを保持 複数の Fragment 間での データ共有 ライフサイクルに紐づいた Observable の一種 ViewModel LiveData

Slide 108

Slide 108 text

Activity および ViewModel はそれぞれ異なるライフサイ クルになっており、 ViewModel のほうが長く生存 するため、Activity の画面回 転でもデータを保持してくれ ます。 ViewModel

Slide 109

Slide 109 text

これはかなりシンプルな MyViewModel というクラ スを作りました。その ViewModel のデータを LiveData として扱うのが一 般的です。なのでこの二つは セットに説明されることが多 くなっています。 ViewModel + LiveData class MyViewModel(private val repo: UserRepo) : ViewModel() { private val _user = MutableLiveData() val user: LiveData get() = _user fun getUser() = repo.getUser() } class MyActivity : AppCompatActivity() { private val model: MyViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) model.getUser().observe(viewLifecycleOwner) { // update UI } } } ViewModel + LiveData Activity

Slide 110

Slide 110 text

ViewModel を使う側の Activity では、その Activity のライフサイク ルを渡すことで、画面が 破棄された後などには データを受診しないよう にすることができます。 class MyViewModel(private val repo: UserRepo) : ViewModel() { private val _user = MutableLiveData() val user: LiveData get() = _user fun getUser() = repo.getUser() } class MyActivity : AppCompatActivity() { private val model: MyViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) model.getUser().observe(viewLifecycleOwner) { // update UI } } } ViewModel + LiveData Activity ViewModel + LiveData

Slide 111

Slide 111 text

実際には ViewModel の なかで、Coroutines や Flows を使って非同期処 理、ストリーム化したり します。 ViewModel + LiveData class MyViewModel(private val repo: UserRepo) : ViewModel() { private val _user = MutableLiveData() val user: LiveData get() = _user fun getUser() = repo.getUser() } class MyActivity : AppCompatActivity() { private val model: MyViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) model.getUser().observe(viewLifecycleOwner) { // update UI } } } ViewModel + LiveData Activity

Slide 112

Slide 112 text

Jetpack Compose

Slide 113

Slide 113 text

Android の UI は現在も XML で構築 していくのが一般的ですが、今年の Google I/O で突然発表された宣言型 の UI ツールキットになります。既存 との互換性も保つよう作られており、 2020年を目標にベータ版が公開され る予定です。現在でも最新の Android Studio を使うことで試すこ とができます。書き方は Flutter っぽ い。 Jetpack Compose @Preview fun HomeScreen(openDrawer: () -> Unit) { val postTop = posts[3] val postsSimple = posts.subList(0, 2) val postsPopular = posts.subList(2, 7) val postsHistory = posts.subList(7, 10) Column { TopAppBar( title = { Text(text = "Jetnews") }, navigationIcon = { VectorImageButton(R.drawable.ic_jetnews_logo) { openDrawer() } } ) VerticalScroller(modifier = Flexible(1f)) { Column { HomeScreenTopSection(post = postTop) HomeScreenSimpleSection(posts = postsSimple) HomeScreenPopularSection(posts = postsPopular) HomeScreenHistorySection(posts = postsHistory) } } } }

Slide 114

Slide 114 text

Jetpack Compose @Preview fun HomeScreen(openDrawer: () -> Unit) { val postTop = posts[3] val postsSimple = posts.subList(0, 2) val postsPopular = posts.subList(2, 7) val postsHistory = posts.subList(7, 10) Column { TopAppBar( title = { Text(text = "Jetnews") }, navigationIcon = { VectorImageButton(R.drawable.ic_jetnews_logo) { openDrawer() } } ) VerticalScroller(modifier = Flexible(1f)) { Column { HomeScreenTopSection(post = postTop) HomeScreenSimpleSection(posts = postsSimple) HomeScreenPopularSection(posts = postsPopular) HomeScreenHistorySection(posts = postsHistory) } } } }

Slide 115

Slide 115 text

Networking

Slide 116

Slide 116 text

Square 社製でデファクトスタン ダードになっています。Android 5.0 以上が最低動作バージョンに なっており、JSON, Protobuf, XML などにも対応 していてとて も使くなっています。 Retrofit (+ OkHttp) 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 }

Slide 117

Slide 117 text

Dependency Injection (DI)

Slide 118

Slide 118 text

Dagger Koin Kodein Java Google 製 慣れるまで難しい 利用実績が多い 高速 JVM, Android Kotlin 軽量で簡単 DSL Kotlin 簡単 マルチプラットフォーム 対応 (JVM Android, JS, iOS)

Slide 119

Slide 119 text

Dagger Java Google 製 慣れるまで難しい 利用実績が多い 高速 JVM, Android

Slide 120

Slide 120 text

Firebase

Slide 121

Slide 121 text

Firebase iOS、Android、ウェブ向けの 包括的な開発プラットフォーム となります。Crashlytics、 Authentication、Cloud Messaging、Test Lab など 様々なプロダクトで採用実績が あります。

Slide 122

Slide 122 text

Test Lab

Slide 123

Slide 123 text

Firebase Test Lab アプリをアップロードするだけ で、Google が管理する複数の実 機及びエミュレータ上で同時に 動作確認ができます。Android の Instrumentation テストにも 対応していて CI から実行するこ とも可能となっています。iOS の XCTest にも対応していま す。

Slide 124

Slide 124 text

Firebase Test Lab Firebase Console からテストの 実行状況が確認できます。 赤い▲がクラッシュした場合の表 示です。

Slide 125

Slide 125 text

Firebase Test Lab アプリがクラッシュした場合には スタックトレースや Logcat を確 認することができます。

Slide 126

Slide 126 text

Firebase Test Lab テスト実行中の端末を終始、画面 録画されて、CPU やメモリなどの グラフも確認できるようになって います。

Slide 127

Slide 127 text

Firebase Test Lab 画面録画だけではなく、動作中の スクリーンショットも確認するこ とができます。

Slide 128

Slide 128 text

2020年はどうなることやら。 Conclusion twitter.com/wasabeef_jp wasabeef.jp github.com/wasabeef Photo by Annie Spratt on Unsplash