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

来年に備えるために Android の知識を網羅する / Looking back on this Android year in preparation for next year.

来年に備えるために Android の知識を網羅する / Looking back on this Android year in preparation for next year.

Daichi Furiya (Wasabeef)

December 14, 2019
Tweet

More Decks by Daichi Furiya (Wasabeef)

Other Decks in Programming

Transcript

  1. activity ads annotation appcompat arch asynclayoutinflater autofill benchmark biometric browser

    Jetpack に含まれるライブラリを並べてみると…
  2. 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
  3. 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
  4. 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+ 個のライブラリ群
  5. 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+ 個のライブラリ群
  6. この場で話す範囲 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)
  7. Security Updates Smart Reply Dark Theme Privacy Controls Family Link

    Live Caption Sound Amplifier Location Controls Gesture Navigation Focus Mode Android 10 Highlights
  8. Location Controls <manifest> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> </manifest>

    バックグラウンドでロケーション 情報を取得するには、また別に権 限を取得しないといけません。
  9. 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
  10. 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
  11. 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
  12. Android Java にはない Kotlin の機能 SAM 変換 拡張関数 データクラス Null-safety

    インライン関数 スマートキャスト Coroutines Flows etc..
  13. 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()
  14. RxJava 非同期処理用ではなくリア クティブプログラミングの ライブラリです。ライフサ イクルに紐づけることもで きます。RxJava の機能全 体を把握するのは難しく、 学習コストが高めです。 val

    observable = Observable.create<Bitmap> { 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) }
  15. val job = launch { println("Hello, Coroutines !!") } job.cancel()

    また、launch 関数は Job クラスを返します。この Job はコルーチンのライフ サイクルのハンドリングを 提供します。アクティブ状 態か完了しているかなどを 把握でき、キャンセルする こともできます。 Job - Kotlin Coroutines
  16. Job では Job 同士を階 層関係で管理することが できます。launch 関数 を呼ぶときに親にあた る Job を渡すことでそ

    れが可能となります。 val parentJob = Job() val job = launch(parentJob) { println("Hello, Coroutines !!") } parentJob.cancel() Job hierarchy - Kotlin Coroutines
  17. Job の階層関係を作るこ とで、親 Job をキャン セルした場合には、子 Job もキャンセルするこ とができます。 Job

    hierarchy - Kotlin Coroutines Parent Job Child Job A Child Job B Child Job C .cancel() .cancel() .cancel() .cancel()
  18. val scope = CoroutineScope(Job()) val job = scope.launch { println("Hello,

    Coroutines !!") } scope.cancel() launch 関数は全て CoroutineScope の中で 実行されます。これまで 省略していましたが、本 来はこのような形になっ ており。そのスコープ内 のコルーチンはキャンセ ルすることができます。 CotoutineScope - Kotlin Coroutines
  19. このスコープを Activity、Fragment や ViewModel に合わせ ることで、Android のラ イフサイクルに紐づける ことができます。 CotoutineScope

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

    を使用する ことができます。 CotoutineDispatcher - Kotlin Coroutines val scope = CoroutineScope(Job()) val job = scope.launch(Dispatchers.Default) { println("Hello, Coroutines !!") } scope.cancel()
  21. val scope = CoroutineScope(Job()) val job = scope.launch(Dispatchers.Main) { println("Hello,

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

    Coroutines !!") } scope.cancel() メインスレッドではな く、データベース、ファ イルの読み書きやネット ワーク通信をする場合に は IO を指定することで パフォーマンスも期待で きます。 CotoutineDispatcher - Kotlin Coroutines
  23. CoroutineScope を生 成するときに、スコープ のデフォルトスレッドを 指定したい場合などに は、+ でつなげること ができます。 val scope

    = CoroutineScope(Job() + Dispatchers.IO) val job = scope.launch { println("Hello, Coroutines !!") } scope.cancel() CotoutineDispatcher - Kotlin Coroutines
  24. Kotlin Flows RxJava と同様に Reactive streams specification Coroutines は One-shotで、Flows

    は Observers として使う RxJava に比べたらやれることが少ない RxJava よりもパフォーマンス向上のためシンプルな設計 受信するまで動作しない(コールドストリーム) 2020年が移行期??
  25. 簡単に使ってみるのは とてもシンプルで、 flow {} ビルダーで生 成して、launch 内で collect 関数を呼ぶこ とで、emit

    された データを受信します。 Kotlin Flows val my Flow = flow { emit("Hello, World!") emit("I'm Flow?") } launch { my Flow.collect { data -> println(data) } }
  26. 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) } }
  27. 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)
  28. Kotlin Multiplatform KotlinConf 2019 でも多く のセッションがありました が、iOS と Android でビジ

    ネスロジックを Kotlin で共 通化するなどの事例が出始 めています。 ※ iOS の UI が作れるものではありません。 Kotlin/LLVM Kotlin/JVM Kotlin/JVM Kotlin/JS Common code
  29. 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 に 寄せて開発しているプロダ クトの事例もあります。
  30. 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 には多く 存在します。
  31. 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 には多く 存在します。
  32. 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 には多く 存在します。
  33. 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
  34. 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+ 個のライブラリ群
  35. AppCompat 必ず使うことになるライブラ リで Android アプリ開発で は、古い OS の対応などがと ても困難でありそれらの問題 を吸収してくれるサポートラ

    イブラリとなります。 import androidx.appcompat.app.AppCompatActivity public class AppCompatActivity extends FragmentActivity implements ... { }
  36. Android KTX Jetpack に含まれる Kotlin の拡張機能セッ ト。コードをシンプルにす ることができます。 view.viewTreeObserver.addOnPreDrawListener( object

    : ViewTreeObserver.OnPreDrawListener { override fun onPreDraw(): Boolean { viewTreeObserver.removeOnPreDrawListener(this) something() return true } } )
  37. 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
  38. Lifecycle Repository Local Source Room Remote Data Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide

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

    Retrofit/okHttp https://developer.android.com/jetpack/docs/guide 単純なボタンクリックか ら、アプリバーやナビゲー ションドロワーなどの複雑 なパターンまで、さまざま なコンテンツ間を移動する を実装するに便利です。 Activity/Fragment
  40. ナビゲーションエディター で設定することもできます が、それらは全て XML で 定義されています。なので もちろん直接編集すること ができますし、直接編集し て XML

    を整理したりする こともあります。 Navigation <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http: //schemas.android.com/apk/res/android" xmlns:app="http: //schemas.android.com/apk/res-auto" xmlns:tools="http: //schemas.android.com/tools" android:id="@+id/nav_graph" app:startDestination="@id/fragment_home"> <fragment android:id="@+id/fragment_home" android:name="jp.wasabeef.navplayground.home.HomeFragment" tools:layout="@layout/fragment_home"> <action android:id="@+id/to_dashboard" app:destination="@id/fragment_dashboard" /> </fragment> <fragment android:id="@+id/fragment_dashboard" android:name="jp.wasabeef.navplayground.dashboard.DashboardFragment" tools:layout="@layout/fragment_dashboard" > <argument android:name="id" app:argType="string" /> </fragment> </navigation>
  41. ViewModel + LiveData Activity/Fragment Repository Local Source Room Remote Data

    Source Retrofit/okHttp https://developer.android.com/jetpack/docs/guide これらを使うことによりライ フサイクルを意識した方法 で UI 関連のデータを保存お よび管理できます。 ViewModel LiveData
  42. これはかなりシンプルな MyViewModel というクラ スを作りました。その ViewModel のデータを LiveData として扱うのが一 般的です。なのでこの二つは セットに説明されることが多

    くなっています。 ViewModel + LiveData class MyViewModel(private val repo: UserRepo) : ViewModel() { private val _user = MutableLiveData<User>() val user: LiveData<User> 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
  43. ViewModel を使う側の Activity では、その Activity のライフサイク ルを渡すことで、画面が 破棄された後などには データを受診しないよう にすることができます。

    class MyViewModel(private val repo: UserRepo) : ViewModel() { private val _user = MutableLiveData<User>() val user: LiveData<User> 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
  44. 実際には ViewModel の なかで、Coroutines や Flows を使って非同期処 理、ストリーム化したり します。 ViewModel

    + LiveData class MyViewModel(private val repo: UserRepo) : ViewModel() { private val _user = MutableLiveData<User>() val user: LiveData<User> 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
  45. 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) } } } }
  46. 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) } } } }
  47. Square 社製でデファクトスタン ダードになっています。Android 5.0 以上が最低動作バージョンに なっており、JSON, Protobuf, XML などにも対応 していてとて

    も使くなっています。 Retrofit (+ OkHttp) interface SampleService { @GET("users/{user}") fun getUser(@Path("user") user: String): Deferred<User> } 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 }
  48. Dagger Koin Kodein Java Google 製 慣れるまで難しい 利用実績が多い 高速 JVM,

    Android Kotlin 軽量で簡単 DSL Kotlin 簡単 マルチプラットフォーム 対応 (JVM Android, JS, iOS)
  49. Firebase Test Lab アプリをアップロードするだけ で、Google が管理する複数の実 機及びエミュレータ上で同時に 動作確認ができます。Android の Instrumentation

    テストにも 対応していて CI から実行するこ とも可能となっています。iOS の XCTest にも対応していま す。