heihei blog

Blog icon by Unsplash https://unsplash.com/@virussinside

Parcelizeを利用してみた所感と注意点

※2018/06/14(木) 時点での所感と注意点を記載しています。何かアップデートがあれば随時追記していければと思います。

Parcelizeとは、Kotlinが提供するAndroid開発のためのコンパイラ拡張機能です。Parcelableを実装したクラスに対して@Parcelizeアノテーションを付与することで、Parcelable実装に必要なコードを自動生成してくれます。

詳細は下記を御覧ください:

github.com

今担当しているプロダクトでは、以前からParcelableに関するライブラリとしてParcelerを利用しているのですが、Parcelizeに関して最近Androidバージョン4.3の端末でインストールできない不具合が直った旨のツイートを見つけ、ちょうど機能改修のタイミングでもあったので導入に踏み切りました。

所感

Android Studioで利用していますが、今のところ不具合なく動いているようです。"Show Kotlin Bytecode"によってどのようなコードが生成されるのかもひと目で確認できます。

注意点

lint実行時にエラー

現状@Parcelizeを付与しているクラスに対してlintを実行すると、エラーが出てしまうという問題があります。

"This class implements Parcelable but does not provide a CREATOR field" 

(AS上でも似たような文言のWarningが出てしまう不具合があったようですが、そちらはすでに修正されています。)

このlintエラーの一時対応策は二種類ありそうです。一つは、エラーを完全無視する方法です。

android {
  lintOptions {
    abortOnError false
  }
}

これは、他のlintのエラー等含めてまるっと無視する設定なので、イケてなさそうな気がします。

もう一つの方法として、対象のクラスのみに対して@SuppressLintアノテーションを付与する方法があります。

Issue Tracker上のコメントにて紹介されていました。

https://youtrack.jetbrains.com/issue/KT-19300#comment=27-2853193

例としてはこのような形です:

@SuppressLint("ParcelCreator")
@Parcelize
class MyParcelable(val data: Int): Parcelable

できればこのアノテーションすら付与したくないところではありますが、一時対応策としてはこれが一番しっくりきました。

もし、何かもっと良い方法等ご存知の方いたら教えていただけると幸いです。m(__)m


※06/14(木)追記

lintOptions {
  ignore "ParcelCreator"
}

という設定でParcelCreatorに関するlintエラーを無視する、という設定もできるようです!@stsn_jpさんありがとうございますm(__)m


View Bindingも有効になってしまう

Parcelizeを利用するにあたり、Kotlin Android Extensionsを有効にする必要がありますが、現状これを有効にすると自動的にView Bindingのほうも有効になります。Data Binding等を利用しているプロジェクトでは、View Bindingは無効にしたいというニーズがありそうです。こちらは今後Parcelizeのみ有効化、等の設定ができようになると最高そうだと感じています。


※06/18(月)追記

androidExtensions {
  experimental = true
  features = ["parcelize"]
}

という設定でParcelizeのみの有効化が可能なようです。@stsn_jpさんありがとうございます!


まとめ

  • Parcelize今のところよさそう。自分のプロジェクトでは現状利用しているParcelerを置き換える流れに持っていく予定。
  • 現状の問題点としては"PacelCreator"Lintエラーが出てしまう点とView Bindingも有効になってしまうのでそこだけ注意が必要そう。
    • ※06/18(月)追記: Parcelizeのみ有効にする方法は上記に記載
    • Lintエラーに関しては、個別に@SuppressLint("ParcelCreator")するのが良さそう。

以上です。

2018年5月を振り返る

2018年も約43%が終わったようです...(; ・`д・´)汗 ※6/5(火)時点

それでは5月を振り返ります。

5月やったこと

Google I/O 2018に参加した

参加してきました。

Google I/O 2018についての振り返りや、いくつかのセッション動画を観た際の英語メモなどに関しては下記を御覧ください。

shoheikawano.com

本業の振り返り

Google I/O 2018参加以外では、振り返ると、

  • モジュール化作業を始めた
  • Bitrise×fastlaneを使った自動化

あたりを今月はわりと集中・意識していました。

モジュール化作業を始めた

今回のGoogle I/OにてaabやDynamic Features、Instant Apps最大アプリサイズの10MB化などがあり、モジュール化の波がAndroid界隈で一気に加速したのではと考えています。自分の所属するチームでは、個人的には@kgmyshinさんのこちらのDroidKaigi 2018での発表内容も参考にしつつ、まずはレイヤーごとにモジュール分けを行い、その後各レイヤーのクラス群からそれぞれ意味あるまとまりごとのモジュールに分けたらどうだろうかなと考えていたのですが、チーム内の数名で話し始めた程度ではありますが、commonとappに分けたあとはもう意味あるまとまりで分け始めるのもありなのでは、という話をしていたりします。つまりまだふわふわっとしているわけですね。社内・社外問わず、既存プロダクトに対してモジュール化を進めている皆さん、ここらへんどうやって進めていますか?

Bitrise×fastlaneを使った自動化

Bitrise × Fastlaneが思いの外いろいろと設定できてよさそうなので、もっと活用していきます。

最近これらのツールを使って、

たとえばtagを切ったタイミングで、

  1. 署名付きAPKを生成
  2. Changelogを生成
  3. GitHub Releasesに新しいDraft Releaseを作成
  4. descriptionにChangelogを入力
  5. assetsとして署名付きAPKをアップロード
  6. SlackにDraft Releaseでけたよ通知

させたりしています。今までは独自のスクリプトだったりを使ったりしていたのですが、たとえばChangelog生成、やGitHubのRelease作成、APKをGithubのReleaseにアップロードする等はfastlaneが用意してくれているactionで、Bitriseの機能のみで実現できました。(「そんなのもうやってるよ」という声が聞こえてきそうですがスルー)

自動化周りで困ったこと、詰まったことやそれらを自分なりにどう解決したかについては6月のpotatotips@FOLIOにて発表予定です。

その他

  • 個人アプリにアップデートリクエストが来た

ここはマイペースにやっていくしかない。

バロンドール受賞した!というニュースをSNSかどこかで見て、見てみようと思った感じです。「あ、こういうのいいなぁ(´ェ`)」と思うシーンや、鳥肌が立つほどジーンとくるシーンなど、いろいろな波のある映画でした。安藤サクラさんの演技が特に印象的でした。

以上になります。5月もお疲れ様でした!

Google I/O 2018で質問したこと・I/O 2018の振り返り

f:id:shaunkawano:20180521192251j:plain

Google I/O 2018の発表内容についてはこのブログでは紹介していないので、発表内容について気になる方は他ブログ・Qiita記事だったり各地で開催されている報告会の資料などをぜひ参考にしてください。

本記事では、Google I/O 2018にて質問したこと(したかったこと)と回答、会場でGoogleの方と交流できる場所について共有をして、I/O期間中を振り返ってもっとこうすればよかったな、ということを振り返ります。

Google I/O 2018にて質問したこと(したかったこと)

現地に行く前に事前に社内のエンジニアの方々に何か質問しておくことはないか等聞いたり、誰でも編集可能なスプレッドシードをツイートを通して共有しておき社外の人からも質問を募ったりしました。 その結果なのか、10+の質問をもらうことができ、いくつかのものに関して回答を得ることができました。

docs.google.com

冒頭にも書きましたが、全部の質問はすることができませんでした。(残念に思ってしまった方、すみません。)

質問と回答

現地では回答を得れたものから適時Q. A.という形でツイートしていました。下記はその一覧です

(上記はKTXの発表前に質問しました)

こうやってみると思ったより質問できたこと少ないことに気づきますね...

個人的にはRealtime DBの不安定感に対する質問を投げかけた際の、社員さんの申し訳なさそうな顔が印象に残っていて、「がんばってください!」という応援の気持ちです。

I/OでGoogleの方と交流できる場所

Google I/Oではキーノートやセッションの他に、サンドボックスやオフィスアワーといったGoogleの方と交流するためのスペースが設けられています。

サンドボックス

サンドボックスには、Googleの製品や製品を用いた作品のデモ、実演などの他に、キーノート、セッションなどで発表された開発ツールなどの使い方の実演などを行なう専用スペースです。

Android & Pay、AR/VR、Web & Payments、Cloud, Firebase & Flutter、Android Things & Nestといった各セクションごとにドーム型のスペースが設営されており誰でも自由に出入りすることができます。中にはデモやツールの説明を行なうGoogleの方がいて、気軽に話しかけたりすることができます。

f:id:shaunkawano:20180521192442j:plain

f:id:shaunkawano:20180521192513j:plain

オフィスアワーとアプリレビュー

オフィスアワーでは、Googleの方に個別で質問をすることができます。オフィスアワー専用のスペースには、一定の時間ごとに各分野のGoogleの専門家の方がいて、その所定の時間に出向くことで、自分の興味のある分野のGoogleの専門家の方に質問することができます。

アプリレビューでは、自分のアプリをレビューしてもらい、具体的なアドバイスだったり改善点などを教えてもらうことができます。

f:id:shaunkawano:20180521192539j:plain

個人的にオススメの交流・質問場所

アプリレビューをお願いしたい場合には事前に予約をして所定の時間に所定の場所に出向く必要があるため、まずは予約をしておくことが大切のようです。(最終日に現地でアプリレビューを行きたかったが予約で埋まっていてできませんでした)

質問や交流をする場合には、個人的にはサンドボックスがオススメだと思います。オフィスアワーでももちろんできますが、オフィスアワーは本当に「質問をするためのスペース」なので、たくさんの参加者の方がいてGoogleの方に質問をしています。サンドボックスの場合は、デモや作品などの展示があるので、そういった物を介して交流することができるので話しかけやすいと感じました。もちろんサンドボックス内の展示の周りにもGoogleの方はいるので、質問したいけどGoogleの方がいない、ということはありませんでした。

振り返ってみて次はこうしたいと思うこと

期間中を振り返ってみて、もっとこうしておけばよかったということについて振り返ります。これは質問とか交流とかはあまり関係なく、次また当選したりするなどでI/Oに行く機会があれば、こうしたいなーフワフワと思っていることです

  • 初日のキーノート・ディベロッパーキーノートが終わったらcodelabに入り浸る

初日のキーノート・ディベロッパーキーノートが終わってすぐは、わりとcodelabが空いています。codelabスペースでは、用意されているPCや持参しているPC・ラップトップを用いてI/Oで発表された内容等を含めたcodelabを行なうことができます。今回codelabに参加して気付いたことは、codelabの説明内容がセッションの発表内容そのものとかなり重なっているということです。初日1つ2つのcodelabを終えてcodelabと同じトピックのセッションを聴講したところ、内容がかなり頭に入ってきやすかった印象です。codelabで内容を一通りコード上で触り終えているのでセッションは復習のような形として捉えるようなことができました。もちろんリアルタイムで聴講していない分、ホテルに戻ってセッション動画等を見直す必要はありますが、いきなり新しい内容の発表をセッションで学ぶよりは一度codelabを挟んでおいたほうが理解し易そうです。

  • もっと他国からの参加者と友達になる

言わずもがな。今回スウェーデン出身で同じホテルに宿泊していたステファンさんに声をかけてもらい、会場に一緒に向かう道中でお話したりして楽しかったので、次回はもっとこういう人を増やせたらなと欲張りになっています。

  • 日焼け止めをちゃんと塗る

うん、ちゃんと塗ろう(๑•̀ㅂ•́)و✧首元、耳とかの日焼けがあってヒリヒリした

  • 目薬を持参する

ところどころ目が(δ´ω`)カユかったので、持参したほうがよさそう

まとめ

今年のGoogle I/Oでは、出発前からできるだけ色々な方から質問をもらっておいて、頑張って質問して回答を得ようと考えていました。理由は明白で、質問や交流をするという行為に対する心理的ハードルを下げることができるからです。質問や交流をするのは何かと勇気が必要で、嫌な顔されないかな、とか変な質問じゃないかな、とか色んな理由をつけて避けたくなる傾向が自分はあるのですが、質問して欲しい内容をもらったからには、できるだけ質問しなきゃ、と自分を奮い立たせることができます。英語の練習になるのはもちろん、当たり前だけど自分が知らないことを知るきっかけにもなります。キーノートやセッションでは発表されないような内容のことであっても、とりあえず投げかけてみて、現状のステータスだったり、今後はこうするかも、といった方針だったりを教えてもらえることもあります。(もちろん教えてもらえないこともあります。)Win-Win-Winくらいのメリットがありそうだと思えると、できるだけたくさん質問しようという気になりました。

他の方にも、質問を受け付けて回答を持って帰っていらっしゃる方がいました。キーノートやセッションの内容は毎年モリモリでキャッチアップも大変ですが、公式の大きい発表以外にも、どんどん方針だったりグレーゾーンのようなところの情報を集め今後の流れを少しでも察知して、大きなアップデートに備えていきたいです。

最後に、一般参加枠で現地に行かせてくれた弊社に感謝して締めます。ありがとうございました。 🙏

Notes - Android Jetpack: what’s new in Android Support Library (Google I/O 2018)

※Notes記事では、英語のセッション動画やポッドキャストの内容を(雑に)英語でメモに書き残すことを行っています。本記事は、あくまで動画を見ながら、参考程度に読んでいただくことを想定しています。Notes記事には雑メモ程度のものだったり、書き起こしのようなものもあります。これから実際の動画を見る際には、本記事の内容が少しでもお役に立てば幸いです。(内容において不備、誤字脱字等ありましたら気軽にご連絡いただけると嬉しいです!m(__)m)

本記事は、Android Jetpack: what’s new in Android Support Library (Google I/O 2018)の記事です。

f:id:shaunkawano:20180514095248p:plain

Packaging

Current Package Name

  • com.android.support
    • support-v4
    • support-v13
    • appcompat-v7
    • cardview-v7
    • gridlayout-v7
    • mediarouter-v7
    • palette-v7
    • preference-v7
    • preference-v14
    • recyclerview-v7

Packaging Versioning Releasing

  • Form of foundation to jetpack: Android Extension Libraries = AndroidX

Jetpack

  • Guidance
  • Recommended libraries and tools
  • Has a cute logo

AndroidX

  • Libraries itself
  • Technical guarantees
  • Does not have a cute logo

Finer-grained artifacts

  • Feature-based Maven groupId and artifactId
  • Scoped to individual widgets, use cases
  • Compatible with old artifacts
  • Binary compatible

Refined versioning

  • Reset from 28.0.0 to 1.0.0
  • Strict semantic versioning
    • Major - binary compatibility
    • Minor - feature release
    • Bug fix
  • Per-artifact versioning & release
  • Dependencies defined in POM

Updated packaging

  • Refactored to androidx java packages
    • 1androidx..ClassName`
  • Consistent Maven naming schemes
    • androidx.<feature>:<feature>-<sub-feature>
  • Removed -v7, -v4, etc. naming

Examples

Support Library 28.0.0-alpha1 => AndroidX 1.0.0-alpha1
com.android.support:multidex
=> androidx.multidex:multidex

com.android.databinding:adapters
=> androidx.databinding:databinding-adapters

android.arch.persistence.room:common
=> androidx.room:room-common

com.android.support:support-compat
=> androidx.core:core

com.android.support:cardview-v7
=> androidx.cardview:cardview

Migrating to AndroidX

  • Tooling for automatic source migration
    • Available in Android Studio 3.2 Canary 14+
    • Wait until Canary 15 to start using this
  • Jetifier tool for prebuilt JAR, AAR transformation
    • Available as standalone JAR or Gradle plugin
  • Use Automated refactoring(As of 05/12/18: Available now in Android Studio 3.2 Canary 14)

    • "Refactor to AndroidX…"
  • Support Library 28.0.x

    • Parity with AndroidX 1.0.x libraries
    • Same old android.support java package
    • Same old com.android.support Maven groupId
  • No feature releases after 28.0.0

What's New Features

RecyclerView Selection

  • Touch and mouse-driven
  • Preserves state between Activity lifecycle events
  • Finger-grained control
dependencies {
  implementation "androidx.recyclerview:recyclerview-selection:1.0.0-alpha1"
}
  • Band selection
  • Item selection area
  • Item rejection
  • State management
  • Much more

RecyclerView ListAdapter

  • Operates on immutable lists
  • Simplified way to use DiffUtil
  • Provides animated updates
  • Concurrency support
  • Efficiently animates changes
  • See also AsyncListDiffer

androidx.webkit

  • Provides access to latest WebView platform APIs(android.webkit.*)
  • Relies on updatable WebView APK
    • API 21+ devices only
dependencies {
  implementation "androidx.webkit:webkit:1.0.0-alpha1"
}

Browser library

  • android.support.customtabs -> androidx.browser
  • Custom tabs supported by major browsers
  • Browser actions
    • Allows apps to hook into browser context-click menu
    • Requires browser support: Chrome v66+

HeifWriter

Slices

Android's new approach for remote content

  • Templated
  • Interactive
  • Updatable

Backwards-compatible through API 19+(95% of devices)

Goal

  • One reusable API for presenting remote app content in Android
  • Templated and Interactive

Launching in Search

Enhance Suggestions with rich, live app content

  • App names
  • General terms

Reach hundreds of millions of users with Slices backwards-compatibility

dependencies {
  implementation "androidx:slice-builders:1.0.0-alpha1"
  implementation "androidx:slice-view:1.0.0-alpha1"
  implementation "androidx:slice-core:1.0.0-alpha1"
}

Slice Types

  • Shortcut slice
  • Small slice
  • Large slice

Material Components

  • Adding more customization for color, type, and shape
  • New components
  • Animations
  • Express your brand
dependencies {
  implementation "com.google.android.material:material:1.0.0-alpha1"
}

所感・まとめ・個人的に印象に残ったことなど

  • Automatic Source MigrationはCanary 15から
  • Jetifier名前良い..どういう仕組みとか知るためには紹介されていた動画を見る
  • What's new in Android Support Libraryが来年からWhat's new in AndroidXになる!
  • Androidアプリ開発を始めてから今まで、Androidのサポートライブラリ系のパッケージング周りよくわからなかったので、今回androidxに統一されて分かりやすくなるの最高そう!

以上です!

Notes - Android Jetpack sweetening Kotlin development with Android KTX (Google IO 18)

※Notes記事では、英語のセッション動画やポッドキャストの内容を(雑に)英語でメモに書き残すことを行っています。本記事は、あくまで動画を見ながら、参考程度に読んでいただくことを想定しています。Notes記事には雑メモ程度のものだったり、書き起こしのようなものもあります。これから実際の動画を見る際には、本記事の内容が少しでもお役に立てば幸いです。(内容において不備、誤字脱字等ありましたら気軽にご連絡いただけると嬉しいです。)

本記事は、Android Jetpack sweetening Kotlin development with Android KTX (Google IO 18)の記事です。

f:id:shaunkawano:20180514094438p:plain

Last Year at Google I/O

  • We are allowed to extend Android APIs to have new ways of writing Android types.
  • Create more concise version of what we intended to do
  • Intend is to feel semantically equivalent

Why can't we directly offer APIs for it? => Lambda matters

When we pass lambda in Java 8 or in Kotlin by default it has to create anonymous class which eats a method and causes a class loading.

inline

  • Language functionality which allows us to eliminate lambda's allocation
  • By marking a function with inline, the body of the function gets copied inside the caller side, so we have zero overhead.
inline fun ViewGroup.forEachIndexed(action: (Int, View) -> Unit) {
  for (index in 0 until childCount) {
    action(index, getChildAt(index))
  }
}

val userLayout: ViewGroup = findViewById(R.id.users)
userLayout.forEachIndexed ( index, view -> 
  // Do something
)

reified

  • Compiler trick
  • Forces the type information of the generic to be known at the compile time so that it can be made available at runtime
inline fun <reified T> Context: systemService(): = 
  ContextCompat.getSystemService(this, T::class.kava)

val notifications = systemService<NotificationManager>()
var onlyDigits = true
for (c in phoneNumber) {
  if (!c.isDigit()) {
    onlyDigits = false
    break
  }
}

Kotlin has a extension function isDigit() so we can use it with all {}:

val onlyDigits = phoneNumber.all { it.isDigit() }

But Android already has a built-in function:

val onlyDigits = TextUtils.isDigitsOnly(phoneNumber)

We can create a extension function for it:

inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)

But, is it worth it to extract it as extension? => YES - More natural - With extension, the IDE will show this with auto-complete so you can easily find this API and you can simply press it to use it.

Android KTX

core-ktx -> support-compat -> Android framework
↓
core-ktx -> core -> Android framework
fragment-ktx -> fragment
palette-ktx -> palette
collection-ktx -> collection
lifecycle-reactivestreams-ktx -> lifecycle-reactivestreams
sqlite-ktx -> sqlite
navigation-*-ktx -> navigation-*
work-runtime-ktx -> work-runtime

KTX Principles

  • Adapt existing functionality and redirect features upstream
    • The body of KTX can be just an alias of current Android APIs
    • The implementation of functions should be trivial
  • Default to inline unless code size or allocation is prohibitive
    • If you write Kotlin by your own making inline as default may not be the best way as it may lead to have more overhead
  • Leverage features unique to Kotlin

  • Code golf APIs to be as short as possible
    • KTX is not there to make the code shorter
  • Optimize for a single and/or specific use case

Reference

API reference  |  Android Developers

Android Developers Reference now contains some of the KTX extension functions

  • Extension Function Summary

Building Kotlin-friendly Libraries

Port public API or entire library to Kotlin

  • May not viable for Android Framework or androidx.* libraries
    • Maybe in the future, strongly possible

Ship sibling artifact with Kotlin extensions

KEEP-110

Kotlin Evolution Enhancement Process

@ExtensionFunction / @ExtensionProperty

  • Turn a static method with at least one argument into an extension function or an extension property
class TextUtils {
  @ExtensionFunction // Tell compiler to have an extension function for this method
  static boolean isDigitsOnly(CharSequence str) {
    int len = str.length();
    // …
  }
}

So in Kotlin side, you can use the extension function made by Kotlin compiler:

val onlyDigits = phoneNumber.isDigitsOnly()

// We no longer need this extension function
// inline fun CharSequence.isDigitsOnly() = TextUtils.isDigitsOnly(this)

// In byte code we get
val onlyDigits = TextUtils.isDigitsOnly(phoneNumber)

@KtName

  • An alternative name for methods, fields, and parameters for use by Kotlin code
  • Advantages
    • You can retain the single source of truth in Java APIs
      • You don't have to add Kotlin code
    • Even in pure Java libraries they can enhance their APIs for Kotlin users

@DefaultValue

Default parameter value

class View {
  void setPadding(
    @KtName("left") @DefaultValue("paddingLeft") int left,
    @KtName("top") @DefaultValue("paddingTop") int top,
    @KtName("right") @DefaultValue("paddingRight") int right,
    @KtName("bottom") @DefaultValue("paddingBottom") int bottom
  ) {
    …
  }
}
avatarView.setPadding(left = 10, right = 10)

// We no longer need this extension function
// inline fun View.updatePadding { … }

// in byte code we get
avatarView.setPadding(left = 10, top = avatarView.paddingTop, right = 10, bottom = avatarView.paddingBottom)

Note

  • Semantics may change
  • Naming may change
  • This proposal may not be accepted and added into Kotlin compiler
    • But some of the prototypes are already in Kotlin compiler

In Bug Tracker we have now new component: Android Public Tracker > App Development > Support Libraries > Android KTX

  • Still accepting PRs, but issues inside GitHub is no longer the single source of truth, Bug Tracker will be.

所感・まとめ・個人的に印象に残ったことなど

  • 具体的な原則をもとにどういう拡張関数を追加するかを吟味することは、Jakeとかしかできないよなぁ
  • Dead code elimination(Fragment Transactionに関する拡張関数)のくだりをみると、Kotlin Compilerがどれだけ賢いかが分かる..
  • KEEP-110がもし採択されたらktxいらなくなりそう、もしくはめちゃくちゃ軽量になりそう、けど、ツイッター上でどなたかおっしゃっていたとおもうけど、Javaのコード上にものすごい量のアノテーションつきそうでそれはそれでつらそう。どうなるのだろうか、どちらにしても楽しみ
    • とはいえ、Androidプラットフォームに適用することにおいてはものすごく恩恵が大きそうなので個人的には実現してほしいなあという印象です..!

以上です!

Notes - Android Jetpack how to smartly use Fragments in your UI (Google IO 18)

※Notes記事では、英語のセッション動画やポッドキャストの内容を(雑に)英語でメモに書き残すことを行っています。本記事は、あくまで動画を見ながら、参考程度に読んでいただくことを想定しています。Notes記事には雑メモ程度のものだったり、書き起こしのようなものもあります。これから実際の動画を見る際には、本記事の内容が少しでもお役に立てば幸いです。(内容において不備、誤字脱字等ありましたらご連絡いただければと思います。)

本記事は、Android Jetpack how to smartly use Fragments in your UI (Google IO 18)の記事です。

f:id:shaunkawano:20180512195201p:plain

The Story so far

Everybody started writing Activity

  • Entry point to your application system
  • main() with lifecycle
  • Creates views
  • Binds view

Enter tables

  • Phone UI + Phone UI = Tablet UI
  • How do I stick two phone UIs together?
  • Enter tables

Fragments of an Activity

  • Design goal of fragments allow splitting up huge Activity classes
  • Requirement: anything an Activity can do, a Fragment can do
    • Lifecycle events
    • Managing view hierarchies
    • Saved instance state
    • Non-configuration instance object passing
    • Back stacks

Can we fix some other APIs?

  • onRetainNonConfigurationInstance
  • Activity#showDialog
  • TabHost/LocalActivityManager

Factoring Activities

  • Recipe for breaking up monoliths:
    • Move loosely related code to separate fragments
    • Repeat

Factoring Activities Fragments

  • Recipe for breaking up monoliths:
  • Move loosely related code to separate fragments
  • Repeat

Things Fragments do

  • Lifecycle hooks
  • Back stack management
  • Retain objects across configuration changes
  • (Instance:)Stateful presence in the FragmentManager
  • Manage a View subtree
  • inflatable, reusable components

Architecture Components

Focuses on doing one thing well

LifecycleObservers

  • Strict ordering callback: Last in, first out
  • Created by you, not recreated via reflection
  • NO stateful restoration by the system
  • Isolated, minimal component, easy to test, easy to inject

ViewModel

  • Instances are created by factory you provide
  • LiveData allows easy (lifecycle aware!) reconnection
  • Replace retained instance Fragments
  • Your Activities or Fragments do not have to know where the data comes from; ViewModel is responsible for getting and passing data

Navigation

Fragments are good to be owner of Lifecycle, ViewModel, and views, so Google wants to make it easy for developers to use.

  • Focusing on making "How you move one screen to another screen" better
  • Works well with Fragments
  • Replaces back stack transactions

Why Fragments in 2018?

Android layering

Package Managing

android.widget vs. android.app
  • android.widget - Mechanism

    • Shows state to the user
    • Reports user interaction events
  • android.app - Policy

    • Defines state to bind to widgets
    • Responds to user interaction and issues changes to model

Inflatable Components

ViewGroups that got too smart

  • Composed high-level controls
  • Self-sufficient
  • Lifecycle aware
  • Inflated attributes can become Fragment arguments

=> Cross-cutting UI policy

  • Self sufficient components
  • Ads
  • Independent info cards
  • Parent doesn't need to be involved in data routing from repository

App Screens

Tastes great with Navigation!

Use Activity just as an entry point, and Fragments for showing actual contents

  • Single-Activity apps
  • Common app chrome, decoupled destinations
  • Transitions and animations managed by Navigation, not by hand
  • Can inflate sub-components to help

DialogFragment

Managing another interaction

  • Interaction with another..
    • Floating UI
    • System interaction
  • Leverage instance state restoration
  • Dialogs, bottom sheets
  • Transient UIs you don't want to lose

Options Menus

We still don't have a great answer for this

Merging menus for your Toolbar

  • Fragments support options menus
  • Common use case: setSupportActionBar
    • Useful for fixed common chrome
    • FragmentPagerAdapter
  • Alternative:
    • Directory manage menus as Toolbar View data

Testing Fragments

Diving Fragment Lifecycles

  • FragmentController drives lifecycle
  • Test your larger components in greater isolation
  • Possible, if not the best interface

Loaders

Now decoupled from Fragments!

  • Rebuild on top of LiveData and ViewModel
  • use Loaders from any LifecycleOwner+ViewModelStoreOwner

Where are we going?

  • Separate desired behavior from incidental behavior
  • Reimplementing existing APIs on top of new primitives
    • e.g. LoaderManager on LiveData
  • Make primitive signals and Activity callbacks available to any interested component
  • If you don't like Fragments, write your own!
    • No more magic
    • Use the same composable hooks
  • Fragments + your components working together
  • android.app.Fragment is now official deprecated

所感・まとめ・個人的に印象に残ったことなど

  • 1つのエントリーポイントに対して1つのActivityを、画面にコンテンツを表示するにはFragmentを利用していこう
    • その際のFragmentのBack Stack管理や画面遷移時のアニメーションなどは全てNavigationに任せようという流れ
  • 使いまわし可能なコンポーネントとして、コンテンツを表示する役割をFragmentに完全に任せることで、再利用可能かつ"つらみ"のないアプリ開発ができるようになる => そのためのAAC、そして今回特にFragmentのために用意されたNavigation
  • Navigationを使うことでFragmentのつらみ、Animation周りボイラープレートコードを開発者が気にする必要がなくなる
  • 未だに"つらみ"のある既存のプラットフォームAPIやサポートライブラリのAPIはあるが、今後はAACなどの新しいAPIの上に乗せる形で作り直すような例も出てくる(LoaderManagerがLiveDataに依存する形で作りなおされたように)
  • 今後はAACを使ったアプリ開発は、より安全かつより早くアプリ開発をする上で必須になりそう

以上です!

Notes - Modern Android development: Android Jetpack, Kotlin, and more (Google I/O 2018)

※Notes記事では、英語のセッション動画やポッドキャストの内容を(雑に)英語でメモに書き残すことを行っています。本記事は、あくまで動画を見ながら、参考程度に読んでいただくことを想定しています。Notes記事には雑メモ程度のものだったり、書き起こしのようなものもあります。これから実際の動画を見る際には、本記事の内容が少しでもお役に立てば幸いです。(内容において不備、誤字脱字等ありましたら気軽にご連絡いただけると嬉しいです!m(__)m)

本記事は、Modern Android development: Android Jetpack, Kotlin, and more (Google I/O 2018)のNotes記事です。

f:id:shaunkawano:20181216214559p:plain

Android History

  • 2008 - Android 1.0
  • 2013 - Android Studio
  • 2014 - ART, RecyclerView
  • 2017 - ConstraintLayout, Kotlin, AAC, Studio Profilers
  • 2018 - ktx, Paging

Tools

  • Layout Inspector
  • Trace View -> Systrace
  • New Profiler Tab in Android Studio
  • Memory Tracking
  • Layout Design
    • ConstraintLayout

Runtime in Language

Dalvik

  • Optimized for Space
  • JIT optimizations not as powerful
  • Slow Allocation/collection
  • Heap fragmentation

So

  • Avoid allocations(e.g. Don't use Enums!)
  • Primitive types are cool

ART

  • Optimized for performance
  • JIT + AOT
  • Faster allocation/collection
  • Heap defragmentation
  • Large object heap

So

  • Allocate as necessary(Yes, even enums)
  • Use appropriate types

But

  • Phones are still constrained
  • Buttery is important

Java

  • Started with Java 1.5
  • Extremely popular
  • Available great tools
  • Slow adoption of newer versions

Kotlin

  • Official support in 2017
  • Close collaboration with Jetbrains
  • Many great features that make code more enjoyable to write & read
  • Android project can contain both Kotlin & Java
  • Lint checks in Android Studio
  • Java -> Kotlin conversion
  • Android Kotlin Extension
  • Kotlin Style Guide
  • Kotlin Interop Guide

Benefits of Kotlin

  • Extensions
  • Inline functions
  • Operators
  • De-structuring assignments
  • Data classes
  • Lambdas

Now, new Java APIs in the platform starting with Android P will follow the code convention of Kotlin that when there is a SAM interface as parameter, it goes at the end of the list of parameters.

APIs

  • AbsoluteLayout => Deprecated
  • LinearLayout => Okay for simple cases
  • FrameLayout => Okay
  • GridLayout => Don't use
  • RelativeLayout => Don't use
  • ConstraintLayout => Use it. 2.0 Soon!
  • AdapterViews

Fragments

  • Complicated
  • Core platform bugs+fixes => Core Platform API @deprecated
  • Use Support Library Fragments
    • Improvements ongoing, plans for more
    • New Navigation component simplifies fragment transactions

Activities

  • Android apps consist of many activities
  • Navigating launches an activity
  • Use single activities when possible
    • One per entry point
  • Richer, more continuous use experience
  • Fragments are not necessary, but can help
    • Navigation component, too

Architecture

  • No recommendation for architecture before

Lifecycle

  • AAC: Lifecyle
    • Fragment implements LifecycleOwner
    • AppCompatActivity implements LifecycleOwner
    • Activity and Lifecycle-Dependent-Thing now gets seprated

Views and Data

  • Activity had too much stuff
    • Views
    • Data for Views
    • Lifecycle tracking
    • Data change tracking

Live Data and ViewModel

  • Activity now only contains Views and reference for ViewModel
  • Activity observes LiveData

Data

  • Do it your own! => Room

Room

  • Local data persistence via SQLite
  • Compile-time validation
  • LiveData integration
Idea from Repository Pattern
Activity/Fragment
↓
ViewModel(contains LiveData)
↓
Repository
-> Model(Room) -> SQLite
-> Remote Data(Retrofit) -> WebService

Data Paging

  • Paging Library 1.0
    • Works with RecyclerView
    • Fine-grained item changes, bindings
    • Uses background threads
    • Flexible data fetching options
    • Integration with Room
    • Boring name

Graphics

  • OpenGL ES 1.0 => OpenGL ES 3.1/3.2, Vulkan
  • Software rendering => Hardware accelerated rendering
  • Nine patches => Vector Drawables
  • TextureView vs SurfaceView => Use SurfaceView, not TextureView
  • Managing bitmaps by hand => Recommended Libraries: Glide, Picasso, Lottie

Final Thoughts

  • Profile your code => Profile your code
  • Avoid work when possible
  • Minimize memory consumption
  • Devices are still resource-constrained
  • Battery life is critical
  • Bandwidth is precious
  • User experience matters

所感、個人的に特に印象に残ったことなど

  • 可能であれば1 Activityに極力しよう、というのを公式として今回方針を明言しているのは大きいなと感じました
  • Java APIの作りもKotlinを意識した形にする、というのは最高そうですね!
  • Navigation Component、AAC LifecycleによってFragmentも扱いやすくなった、というようなわりとFragmentが肯定される内容だったのかなと
  • サードーパーティー製のライブラリも良いものは使っていこう(Retrofit, Glide, Picassoなどが本動画には登場しています)という姿勢も、全て結果的には良いUXを提供しようというところにつながっていて、説得力というか納得感もあり実際それによって開発者も悩み少なく良いアプリを作れる、というWin-Winな形があるなぁと感じました

以上です!