kudo no burogu

技術メモとか勉強会のこととか書きます

「Kotlin Fest 2019」に少しだけ行ってきた

kotlin.connpass.com

セッション一覧

Kotlin Fest 2019 セッション一覧

全体の感想

  • kotlin固有でAndroidに限らないテーマが中心なので、MPP関連が多かった気がする
  • 普段は言語仕様をそこまで意識しないので、深く考えるきっかけになる
  • 皆発表上手

以下、特に印象に残っている内容について

Kotlinの型実践入門

speakerdeck.com

Nothing

  • 値が存在しないことを示す
  • これはコードを見るのが早い
// 処理失敗でUnitを返してしまうと
val unitPattern : Any = if (isHoge) { // Any型になる
  "success"
} else {
  Unit
}

// Nothingにすると 
val nothingPattern : String = if (isHoge) { // Nothing以外で返却される型になる
  "success"
} else {
  Nothing
}
  • プロダクトで利用する良い例が思いつかないけど、失敗時にExceptionを発行するような処理を書くときに使えそう

改めて学ぶContracts

speakerdeck.com

  • そもそもContractsを知らなかったので、この発表を聞きながら理解を深めていった
  • 関数の結果をContract(契約)によって表現する
  • String?.isNullOrBrank のチェック後にアンラップされるのは、結果がnullでないことを関数側から契約で定められてるから、みたいなイメージ。もう少し勉強が必要

Kotlin Serialization ことはじめ

  • jsonでもProtobufでもkotlinでシリアライズできる
  • パフォーマンスはそれほど変わらない
  • jsonのみのAPIならmoshiとかで良い
  • 帰る直前だったので記憶が曖昧。。。資料公開されたらもう一度見たい

「Google Play APP DOJO #38 Android Q 新機能詳細 - ダークテーマから共有機能まで -」に参加してきた

f:id:burgerham:20190618024035j:plain

目的

Google I/O で発表された新機能について、アプリ開発者向けに説明していただけそうだったため(IOの動画をちゃんと見てない・・・)。英語動画が厳しい自分でもキャッチアップできるかなと思った

Twitter -> #appdojojp

全体の感想

内容のボリュームや難易度がちょうどよく、非常にわかりやすかった。なんとなく技術記事で見たような気がする話題も、改めて人に説明してもらうことで理解が深まった気がする。

第 1 部 Android Q 新機能詳細

プライバシー

チェックリストを確認しよう

位置情報

バックグラウンドで位置情報を取得するためには追加でパーミッションが必要になる

Scoped Storage

  • /sdcard以下へのアクセス制限
  • ただし、自分で作成したファイルへはアクセス可能
  • Android Rからは、FileSystemでアクセスできなくなる予定

ダーク テーマ

  • 以前から存在するが、OS設定としてできるようになった
  • 非対応アプリが少数派になったときに、ダークモード設定で未対応アプリを起動したときに悪目立ちする

対応方法

下記のような対応で、ある程度自動でやってくれるとのこと。

  1. テーマ変更 -> Theme.AppCompat.DayNight
  2. 細かく設定することもできる -> values/styles.xmlvalues-night/styles.xml を用意
  3. テーマそのまま、プロパティ追加でも -> これでも結構いい感じになるらしい
<style name="AppTheme" parent="Theme.hogehoge.Light">
    <item name="android:forceDarkAllowed">true</item>
    # hogehoge
</style>

# 一部を除外したいとき
<ImageView
    android:layout_width="match_parent"
    android:forceDarkAllowed="false"  # これ

もちろんxmlファイル上で色を直接指定している場合は変換されない。UIの内容をxml側で表現している場合、ひとまずstyleにまとめていくなどして、きたるべき日に備えていくのが良さそうだと感じた

ジェスチャー ナビゲーション

  • Android Qからは見た目iosのようなジェスチャー操作になる
  • 現在のシステム設定では既存の3ボタン or 戻る/ホームバーの2ボタンが存在するが、Android R以降は 3ボタン or ホームバー1ボタン の2種類になる
  • ジェスチャーの下までコンテンツを表示してるといい感じ
<style name="AppTheme" parent="hogehoge">
    <item name="android:navigationBarColor">@color/red</item>
    <item name="android:statusBarColor">@color/blue</item>
view.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
  • 既存のスワイプ操作とのコンフリクトは、コード側で対応可能
  • 標準のドロワーレイアウトであれば、ライブラリのアップデートでOK

Bubbles

  • FacebookMessenger等で表示される、アプリ長押しで表示できる画面
  • Androidチーム的にはシステムアラートウィンドウは将来消したいらしい
    • フリーダムすぎるらしい
    • Goでも非搭載なので、消えるのは確定みたい
  • Bubblesはそれの代替手段として用意された機能
  • ただし、Android Qでもプレビュー版しか提供されないので、開発者オプションで設定する

有機能の強化

  • Android Mから搭載された、共有パネルが改善
  • DirectShare(名前あってるか自信ない)の領域の表示遅延が改善

SettingsPanel

  • 画面遷移しなくても設定画面を表示できる
  • パーミッション取得時に設定に飛ばしてる画面があるので、そこで活用できそう
  • 表示できるのは設定項目4種類
  • 表示しているのはあくまで設定項目であって、パーミッションではない(QAにて)

QA

  • NavigationDrowerとジェスチャーは動作がコンフリクトするが、NavigationDrowerがなくなるというわけではない
  • ジェスチャーUIになったときに、クリック要素がナビゲーションバーとかぶるのは避けたほうが良い(bottomBarとか広告とか)
    • addApplyInsetsListener (?)の引数で必要な高さが取得できるので、それを活用してマージンを設定するのが良い

第 2 部 Jetpack 最新情報

既存のライブラリの新機能

ここはコードが多かったので概要だけ

LiveData & ViewModels

kotlin firstの一環で、いろんな構文がより短くスマートにかけるようになった

DataBinding

Android Studio 3.5で書きやすくなった -> インクリメンタルアノテーションプロセッサー

savedState

ViewModelはメモリ上にデータを保持するので、プロセスが中断されるとデータが消えてしまう。そういう場合もデータを保持したい場合はviewModelで SavedStateHundle を使おう

WorkManager

foregroundでもつかえるようにする予定(WorkManager自体よくわかっていないので記憶が薄い)

Room

Paging

  • ネットワークからの取得を用意に
  • ヘッダー、フッダー
  • RxJava

CameraX

  • 内部でcamera2apiを使っているが、抽象化して簡単になっている

ベンチマークライブラリ

  • Junit等で結果を出力できる
  • これだけでよくなるわけではないが、CIで監視することで品質が一定であることを証明できる

セキュリティ

端末から抜き出せないようになっている秘密鍵を使って暗号化することで、万が一データを見られても解読できないようにする

  • EncryptedFile
  • EncryptedSharedPreferences
    • tokenなどをSharedPreferencesに保存してたので、これはめちゃくちゃ便利そう

QA

  • 今後cameraXの機能追加はあるのか
  • フォーラムから要望を出してくれれば、検討して実装されるかもしれない。実際今もどんどん改善されている

APP DOJO プログラムマイナーチェンジについて

developers-jp.googleblog.com

  • Playストア表示ロジックが変更される
  • 良いアプリはより目立つ位置に掲載され、それが反映されるようなランキングロジックになる
  • これに則した活動になるように改善される予定とのこと

DroidKaigi2019/02/08(二日目)

Android App Improvement Challenge Part1: 機能実装編

  • 機能追加した
  • 30分だけ参加だったのでリストに時間を表示するissueのみ

Slice Your App: Inside Slices and How to build it

  • Google検索やAssistantにコンテンツ表示する際に使用する
  • AppIndexingの仕組みと一緒
  • Sliceのスレッドで通信やレスポンスを一定時間内に返却できない場合に死んでしまうので、一度ローディングViewを表示した後データ取得後に再描画すれば良い
    • Sliceはアプリ内ローカルデータしか表示できないものだと勘違いしてた
  • パラメータとして時間を持っているため、単純比較のassertではテストできないので、パラメータを適切にフィルタリングする必要がある

Android App Improvement Challenge Part 2: リファクタ編

  • ヒントブランチ読んでたら終わってしまった・・・

Android Studio設定見直してみませんか?

  • とにかく楽しめた
  • 自分用リストを作ることに決めた

今日から始める依存性の注入

  • 外部から依存関係を注入することで疎結合を実現する。それをすることでアプリを拡張しやすくなったりテストしやすくなる
  • DIにもスコープがある
  • なんとなくわかってきたらgithub上のコードを読んでいくのが理解への近道とのこと

multi-module Androidアプリケーション

  • メリット
    • ビルドの高速化につながる
    • build variantの変更で開発ビルドを分けている場合、プロジェクト外のコードはリファクタ対象外なので修正しづらい。その辺が解消する
  • compile→api or implementationに変更
  • api 参照先が変更されたらすべて再コンパイル
  • implementation 直下が変更されたときだけ再コンパイル
  • どのような構成だと恩恵を受けられるか
    • 資料参照
  • 既存モノリシックプロジェクトをマルチモジュール化する場合
    • 一旦最低限必要なもの(applucationクラス)とそれ以外で分ける
    • 新規機能は個別のモジュールに
    • 新規機能と既存機能で共通する機能を別モジュールに
    • 既存機能は必要以上にモジュール分割しないほうが良い(機能開発が進まなくなるので)

実践 WorkManager

  • WorkManagerを使ってバックグラウンドで画像をキャッシュした話
  • タイムアウトがあるので分割必要

Google Play Consoleのリリーストラックを有効活用してリリースフローの最適化を行った話

  • masterブランチを自動でアルファリリースするようにfastlaneを書いた
  • リリース前レポートを軽いテストとして活用しようとしたが、通知が貧弱だったため断念
  • アルファ→本番リリースは手動

DroidKaigi2019-02-07(一日目)

ウェルカムトーク

  • 最初のムービーかっこいい

マルチモジュールなプロジェクトでテストはどう変わる?

  • テストを書く意識は上がった
  • PITが便利そうだった
    • コードの変更で今書いているテストが失敗するか?を確認することで、テストケースの妥当性を判定してくれるライブラリ

マルチモジュールプロジェクトでのDagger2を用いたDependency Injection

  • DIの利用により疎結合となり、コンポーネント間の依存性が下がることで、テスタビリティが上がる
  • Daggerは どこに 何を injectするかを定義する
    • 何を → module
    • どこに → component
  • fragmentInjectorが複数のinjectorを持てるように実装することで、マルチモジュールにも対応できる

LiveData と Coroutines で実装する DDD の戦術的設計

  • 昨年よりも、より実践に近いDDD講座
  • 話すペースや声のトーンがちょうど良く、すごく聞きやすかった。
  • ユビキタス言語を探しながら、値オブジェクトやエンティティを定義していく
  • idをIntではなくエンティティにするという発想が新鮮だった
// OK
  data class Session(val id: SessionId)
  data class SessionId(val value: Int)
// NG
  data class Session(val id:Int)
  • モデルの形式が保存形式(DBの情報)と一致させる必要はない
  • 例えば、セッション一覧に表示するイベントとして、通常のセッション以外にもウェルカムトークやランチタイムを表示する場合
    • DB的には、Eventテーブルにtypeをもたせて保存する
    • フロントのモデルとしては、typeを使わなくても、 seald class で表現できる
  seald class Event {
    abstract val id: Int
    abstract val userName: String
    data class Session(override val id: Int, override val userName: String,  val title: String) : Event()
    data class Lunch(override val id: Int, override val userName: String) : Event()
  }

ぼくのかんがえた最強のUsecaseの作り方~あるいはビジネスロジックとはなにかという1つの回答~

Redux for Android

  • Reduxについてに実装例
  • オフィスアワーで聞いてみた
    • Q: Storeの初期化はApplicationクラス?
      • A: Dagger使ってるので、そっちで管理されてる。ライフサイクル的にはApplicationと同じ
    • Q: FatStoreにならないか?
      • A: 現状困っていない。ストアが持つ情報がネストしていくので、深くはなるがFatにはならなそう
    • Q: 画面遷移などはReduxで管理しないなら、どこに書く?View側
      • A: Activityなどで、startActivity()やfinish()すればいい
    • Q: マルチモジュールになったらどうすれば
      • 後ろがならんでて焦ってたのか、聞いた内容忘れてしまった・・・

Fireside Chat

  • 何を考えたか、何に苦しんだかをカジュアルに語ってくれた
  • 理解できないところもあったが、こういう情報はなかなかウェブの情報として上がってこないので、すごく助かる

感想

  • 今年は2回目ということもあり、多少余裕があった。
  • コントリビュートできたし、意識して前に座るようにしたし(去年はずっと後ろの席)、オフィスアワーで初質問できた
  • 2日目も頑張る