DroidKaigi 2017 DAY.01 (Mar 9th, 2017) 参加レポート

# 概要
- セミナー名: DroidKaigi 2017
- 日時: 2017/03/09 - 2017/03/10
- 場所: 東京都新宿区西新宿8-17-1 (住友不動産新宿グランドタワー5F)
- ハッシュタグ: [#DroidKaigi](https://twitter.com/hashtag/DroidKaigi)
- CONNPASS URL: https://droidkaigi.connpass.com/event/43942/
- 公式ページ: https://droidkaigi.github.io/2017/
- 参加費 8,000円 (アフターパーティ無し)

- 以下、参加したセッションのメモを記載


# 講演1: ウェルカムトーク / Welcome talk

## 登壇者
- mhidaka さん
- Twitter ID: [@mhidaka](https://twitter.com/mhidaka)

## 概要

- 代表の日高さんからご挨拶
- DroidKaigi の趣旨について説明

## 発表内容

- DroidKaigi の趣旨
  - 技術情報の共有
  - 技術者同士のコミュニケーション

- 何故 DroidKaigi に参加するのか
  - トレンドを知る
  - 日々の課題を共有する
  - テクノロジーを楽しむ

- 行動規範
  - 何かトラブルがあったらスタッフまで

- 海外からの参加者もいます

- 総参加者800名, 総セッション数67

- スポンサー30社
  - CyberAgent, AbemaTV, Google Developer, etc.

- 会場情報
  - セッションが開催される部屋
  - Wifi のパスワード
  - 企業ブース, お菓子部屋, ランチボックスを提供する部屋

- [DroidKaigi 2017 アプリ](https://goo.gl/UaSaaw)の紹介
  - セッション一覧が見れる
  - アプリからフィードバックを送れる


# 講演2: 逆引きマテリアルデザイン

## 登壇者
- 荒木佑一 さん (Google, Developer Programs Engineer)
- Twitter ID: [@yuichi_araki](https://twitter.com/yuichi_araki)
- [スライド](http://yaraki.github.io/slides/droidkaigi2017/#1)

## 概要
- マテリアルデザイン サポートライブラリ
- 概念, ライブラリ

- ライブラリの使い方
  - あるものを活用する
  - カスタマイズの仕方

- アニメーション


## 発表内容
- マテリアルデザイン
  - https://material.io/guidelines/
  - 絶対に従わないといけない、という訳ではなく、書かれてあることを理解した上で、自分の実装したい UI を作ると良い

- ガイドラインは頻繁に更新されます
  - [What's new](https://material.io/guidelines/material-design/whats-new.html) に更新内容が掲載されてます
  - 最近更新された項目:
      - Platforms
      - Accessibility


## マテリアルデザインの紹介

- [Components - Buttons : Floating Action Button](https://material.io/guidelines/components/buttons-floating-action-button.html)
  - よく右下にオーバーレイで表示されるボタンのアイコン
  - 留意点:
      - ナビゲーションには使わず、ボタンが押されたら主要なアクションができるようにする
      - 右下である必要は無い
      - 下の要素を塞いでしまわないように注意

- [Components - Grid lists](https://material.io/guidelines/components/grid-lists.html)
  - 画像や文字を含んだアイテム上にタッチフィードバック
  - タッチフィードバックはすごく重要
  - 画像一覧のうち、一つをタップした時に拡大画像を表示するケースとかで使う
      - タッチフィードバックがあって、反応がすぐに返されるとユーザは安心する
      - View に android:foreground="?attr/selectableItemBackground" をつけるだけ
      - ForegroundLinearLayout にて、実装例あり

- [Patterns - Launch screen](https://material.io/guidelines/patterns/launch-screens.html)
  - アプリを起動して、すぐにユーザが欲しい情報を表示する、というのが本当は理想だが、読み込みに時間がかかる場合は、その間にブランディングロゴを表示するのは良いやり方
  - Activity を起動したら、その背景画像としてブランドを設定して, 時間が経ったら本当の画面を表示させるのが良い
  - ロゴだけのレイアウトを表示させる SplashActivity は「最悪のやり方」っぽい


- @style/foobar vs ?attr/foobar
  - style は属性とその値のマッピング
      - res/values/styles.xml
      
          ```
          <style name="【任意の名前】" parent="【任意の親クラス】">
          ...
          ```

  - theme もスタイルと同じで、属性とその値のマッピング
      - res/values/themes.xml
      - 使い方が違う

  - (注釈) [公式ドキュメント](https://developer.android.com/guide/topics/ui/themes.html)より:
      - style は、ビューのパディング/フォントの色やサイズ/背景色など、ビューの外観を指定するプロパティの集合
          - ビュー単体のレベルでデザインの定義をするのに利用
      - theme は、個々のビューでなく、 Activity やアプリケーション全体に適用されるスタイルとなる
          - アプリ全体のレベルでデザインの定義をするのに利用


- [Components - TextFields](https://material.io/guidelines/components/text-fields.html)
  - テキストの色を変えたい時にどうするか
  - やりかた1:
      - View の app:errorTextAppearance にスタイルを指定して, そのスタイルに色を設定する
      - スタイルを適用する
  - やりかた2:
      - 大元のソースコードから textColorError という要素を上書きすると、色が変わることを読み取ることができるので、そのようにして theme の要素を上書きする
      - theme を適用する


- [Components - Snackbars & toast](https://material.io/guidelines/components/snackbars-toasts.html#snackbars-toasts-usage)
  - Snackbar は下から出てくる通知バーのようなもの
      - 右下にあるボタンを、 Snackbar に被らせない
      - CoordinatorLayout に入れて、要素を指定する (app:layout_insetEdge="bottom"とか) と実現可能


- [Components - Bottom sheets](https://material.io/guidelines/components/bottom-sheets.html#bottom-sheets-persistent-bottom-sheets)
  - スクロールして画面が動いた時に、下にあるボタンなどが上部のタブにくっつけるような動きを実現


- [Motion - Transforming material](https://material.io/guidelines/motion/transforming-material.html#transforming-material-rectangular-transformation)
  - 画像をクリックしたら、画面いっぱいに画像を拡大させながら表示させるような動きを実現する
  - View # animate() とかでもできるが、細かい制御が大変
    - アニメーションの途中でユーザがタップされたらどうすれば良いか、とか

  - Transition API を使うと実現できます
    - API レベル 19 KitKat で導入
    - Activity 間の Transition だけが Transition ではない
    
    - TransitionManager.beginDelayedTransition(root, changeBounds) を呼ぶだけ
    
    - Transition は色々なアニメーションを設定できる
      - 大きさ
      - scale, rotation
      - スクロール位置
      - ImageView の scaleType
      - Fade in/out, Slide in/out, Explode in/out
      - TransitionSet で組み合わせられる


- [Motion - Chreography](https://material.io/guidelines/motion/choreography.html)
  - Path Motion とかを設定すると実現できる
  - でも、実装がかなり複雑
      - 荒木さん自身もつまづいたらしい


## 質問
- Transition のバックポートの予定はあるか?
  - Transition Support API というので API 14 まで対応しました

- Activity Shared Element のバックポートの予定はあリますか?
  - したいけど遅れると思います

- アニメーションを入れすぎてうざったいということがあり得ると思うが、ガイドラインでそういったことは定義されているか?
  - アニメーションの長さはこれくらいに、とかという感じでガイドラインで定義されている



# 講演3: リリース自動化と効率のよいリリースフローを求めて

## 登壇者
- Ryo Sakaguchi さん (Wantedly)
- Twitter ID: [@wakwak3125](https://twitter.com/wakwak3125)
- [スライド](https://speakerdeck.com/wakwak3125/ririsuzi-dong-hua-falsedao-ru-toxiao-lu-falseliang-iririsuhurowoqiu-mete)


## 概要

- リリース自動化について、以下の流れで説明
  - 自動化の雰囲気
  - リリース自動化に関連するツールの紹介
  - 導入準備
  - 導入
  - 失敗しがちなケースと注意点
  - まとめ

- 導入手順というよりも、なんでやるのか、モチベーションを中心に伝える


## 発表内容

- 自動化の雰囲気
  - 目的:
      - ルーチンワーク・定型業務を自動化して、本質的な作業に集中する
      - アプリが多くなったり、多言語化すると大変になる
      - リリース作業を属人化させない

  - こんなことができる
      - Google Play Developer Console に APK ダウンロード
      - ストア情報の更新
      - 監視ツールへの mapping.txt ファイルをアップロード
      - 他にも色々できるけど、やりすぎはよく無い
  
  - 自動化で何が嬉しいか
      - 作業がシンプルになる。オペレーションミスを少なくできる
      - 以下でリリースできたら理想
      
          ```
          git push origin master
          ```
  
  - 想定環境
      - GitFlow
          - ブランチは master, develop, feature, hotfix, release で運用
        
  - CI おすすめ
      - [Werker](http://www.wercker.com/), [Bitrise](https://www.bitrise.io/) がおすすめ
          - 環境構築, ビルドフローのしやすさでは Bitrise がおすすめ
          - Werker は柔軟性に優れる
          
      - Werker
          - Docker でコンテナを好きに作ってビルド環境を自由に組み立てる
          - CircleCI と比べて速い (CircleCI のように 4GB のメモリ制限が無い)
          - だいたい無料
  
      - Bitrise
          - だいたい GUI で完結できる
          - Web コンソールからビルドをスケジュールができる
          - 署名ファイルの管理を手助けしてくれる
  
  - APK アップロードの自動化
      - [fastlane](https://github.com/fastlane/fastlane)
          - gradle だけで完結できない
          - Crashlytics と統合できる
          - fastlane は Google にジョインした (1月23日)
            
      - [gradle-play-publisher](https://github.com/Triple-T/gradle-play-publisher)
          - gradle だけで完結できる
          - Crashlytics と統合できない

  - [Tonkotsu](https://github.com/operando/tonkotsu)
      - アップロードが Google Play/Apple Store にて反映されたら Slack に通知する


- その自動化は本当に必要か?
  - 国内向けリリースする場合は、それほどやる必要は無い
      - 多言語対応されてなければ、リリースにかかる負担がそれほど大きくない
  - 多言語対応してるアプリの場合は、やるべき
      - アップデート文を手作業で繰り返し更新する必要がある
  - 国内向けだけど NDK, Realm, などを使っている場合
      - SPK Split を使っている場合
      - include 'x86', 'armeabi', 'armeabi-v7a'
        のように、アーキテクチャ毎に APK が生成される
          - → APK のサイズが小さくなる
      - APK が多くなるとアップロードの作業が大変になる


- 失敗しがちなケース
  - なんでもかんでも自動化すると、逆に属人化が発生する



# 講演4: エラーと戦うためのデバッグ法

## 登壇者
- 山﨑亮さん (日本経済新聞)
- Twitter ID: [@ymnd](https://twitter.com/ymnd)
- [スライド](https://speakerdeck.com/ymnder/eratozhan-utamefalsedebatugufa)
- [サンプルアプリ](https://github.com/ymnder/CheckLibraryApp)

## 概要

- デバッグに使っているライブラリの紹介


## 発表内容

- [Stetho](http://facebook.github.io/stetho/)
   - Chrome Developer tools で使える、 Android の Debug Bridege
   - 機能
       - View Hierarchy
           - View のリアルタイムプレビュー
           - 虫眼鏡をタップして、エミュレータのどこかの View をクリックすると、Stetho 側の xml 要素がハイライトされる
           - 逆に、Stetho の xml の要素をクリックすると、エミュレータ側で該当する View がハイライトされる
           - View に設定された Padding, Margin が見れる
           
       - Network Inspection
           - 実際に発生したネットワーク通信の一覧、かかった時間を見ることができる
           
       - Database Inspection
           - Chrome Dev tool からアプリ内の DB テーブル / SharedPreference が参照できる
           - Chrome Dev tool から直接 SQL 文の実行もできる
           - Realm プラグインもサポートしている

       - Console
           - Chrome Dev tool > Console から、 ```> context``` で Context の情報をとってこれたりする

       - Dump
           - CrashDumperPlugin: クラッシュさせることができる。 (クラッシュさせた時の挙動のチェック)


- [chuck](https://github.com/jgilfelt/chuck)
  - HTTP inspector for OkHTTP3
  - (Stetho でも見れるが) ネットワーク通信のログを実機から見ることができる
      - Stetho と違って、アプリ内で全て完結されるのが良い


- [Android Debug Database](https://github.com/amitshekhariitbhu/Android-Debug-Database)
  - ブラウザからアプリ内の DB に SQL クエリを投げる
  - Stetho よりも書くコードの量は少ない
  
- LayoutInspector
  - AndroidStudio の Layout のデザインビューから、左下の「共有」アイコンを押すと良い
  - Stetho とは異なって、View に当たっている Theme とかも見れる

- Theme Editor
  - AndroidStudio > Tools > Android > Theme Editor
  - res/style.xml のプレビューができる



# 講演5: Data Bindingで開発を気持ちよくしよう

## 登壇者
- ケノドン・ブノア (Benoit Quenaudon) さん (サイボウズ)
- Twitter ID: [@oldergod](https://twitter.com/oldergod)
- [スライド](https://speakerdeck.com/oldergod/the-data-binding-library)
- [サンプルアプリ](https://github.com/oldergod/DataBindingDemo)


## 概要

- DataBinding の紹介


## 発表内容

- Android によくある問題
  - findViewById, 型キャスト
  - Setter がnagai
  - xml では用意されてないので、プログラム的に View をいじる必要があることがある


- DataBinding だと findViewById とか書く必要がなくなる
  - ButterKnife でも簡単に書けるが、アノテーションが必要

- 便利
  - getString(R.string, Obj1, Obj2, ...) のようなこともできる
  - 他の View の状態 (checked or not) を監視して、View.VISIBLE or View.GONE を切り替え可能
  - xml の中で、コールバックメソッドの指定が可能

- Binding の種類
  - Persistent Binding
     - Model → View で通信
  - Two way data binding
     - Model ↔ View 間で通信

- View の中で "@{}" で書けて、そこで Java の式が評価できる
  - 三項演算子が書ける
  - 四則演算も書ける
  - lamda 式も書ける
      - ただし、複雑になるのでやめたほうがいい

- NullPointerException が不要になる
  - TextView # setText() で、それぞれ null かどうかチェックする必要があったが、
    DataBinding なら不要人ある

- 始めるのは簡単
  - 一つの Activity から始められる
  - 一つの View から始められる
  - One Way DataBinding でも始められる

- [GitHub](https://github.com/oldergod/DataBindingDemo) にサンプルコード上げました
  - 1ステップ毎にブランチをきっていっているので、参考にすることができる

- DataBinding を使っていると、コンパイルエラーが出た時に、エラーのログがたくさん出てきてしまって、最初に見るとびっくりする
  - 慣れてくると、エラーを早く見つけられるようになる


## 質疑応答

- BaseObservable を継承した時、 BR というファイルが作成されルガ、AndroidStudio で警告が出てしまうが、どうしてるか?
  - 解決策
      - ObservableField というのを使う
      - あとは GradleClean とか Invalidate Restart をしたりした

- DataBinding で Margin とか Padding の計算をするのは黒魔術的か?
  - 業務では使ってないです

- RecyclerView にて、リスト要素の増減を制御するには ObservableList をやっているが、サイボウズではどうやってる?
  - 同じく ObservableList をやってる



# 講演6: 実践アニメーション 〜複雑なアニメーションへのアプローチ〜

## 登壇者
- 湯上尚哉 さん (セプテーニ・オリジナル)
- [サンプルコード](https://github.com/citrous/practicalanimation)

## 概要
- アニメーションの実装方法について、基礎的なものから発展的なものまで紹介

## 発表内容

- Android のアニメーションどうやって作るべき?
  - アニメーション画像データがない場合はどうやって作るか?
  
  - Animation 関連の API はたくさんある
      - Animation クラス
      - Transition Animation
      - Property Animation

  - 複雑なアニメーションを実装する場合のアプローチ


- 基本的なアニメーション
  - 移動 (Translation)
      - view.animate().translationX(【x value】).translationY(【y value】).start();
  - 拡大縮小 (Scale)
  - 回転 (Rotation)
  - Alpha


- Material Design でのアニメーション事情
  - ユーザアクションへのフィードバックに、アニメーションを使う
      - Ripple Effect, Transition Animation


- 複雑なアニメーション
  - アプローチ1: 複数の要素を組み合わせる
      - res/animator.xml に AnimatorSet を作って、 複数の objectAnimator を組み合わせる
      - typo が怖い、アニメーションが複雑になってくると読みづらい
      
  - アプローチ2: AnimatedVectorDrawable
      - ObjectAnimator を使って VectorDrawable をアニメーションさせる
      - 使いやすいツールがある: https://romannurik.github.io/AndroidIconAnimator
      - でも、花火みたいな、複数の要素をバラバラに動かす、といったのができるけどすごく大変

  - おすすめアプローチ: ValueAnimator + CustomView 万能説
      - ValueAnimator:
          - API Level11 ~
          - 指定した値を指定した時間内で変化させる






# 講演7: 変更に強いEspressoテストコードを効率良く書こう

## 登壇者
- 外山純生 さん (NTT ソフトウェア)
- Twitter ID: [@sumio_tym](https://twitter.com/sumio_tym)
- [スライド](https://speakerdeck.com/sumio/droidkaigi2017-lets-write-sustainable-espresso-test-rapidly)
- [サンプルアプリ](https://github.com/sumio/espresso-sample-for-droidkaigi2017)


## 概要
- Android の UI テストツールEspresso について紹介
  - 特に、プロダクトの仕様変更に強いテストの書き方について紹介する

## 発表内容

- テストを書くことの目的
  - テスト実施工数を削減する
  - 手順ミス、確認ミスをなくす
  - 回帰試験を自動化する

- Espresso Test Recorder
  - 実際にアプリにて行った UI 操作が、そのままテストとなる
      - うまく動かないこともある

- 変更に強いテスト
  - テストの内容として、"***" (*** はプログラム側で指定) 文字列と書かれたボタンをおす、とする場合
      - → "ログイン" が "OK" に変わると手動で修正が必要

  - PageObject デザインパターン

  - Espresso Test Recorder では上記のことができない。どんなことをすれば良い?
      - Esprresso Test Recorder 具体的な修正方針をイメージする
      - AndroidStudio のリファクタ機能を使う
  
- 変更に弱いテスト
  - テストの内容として、"ログイン" 文字列と書かれたボタンをおす、とする場合
      - → "ログイン" が "OK" に変わると手動で修正が必要

- Espresso で不得意なこと、困難なこと
  - View のプロパティの動的な取得
  - 操作・確認対象が明確でないケース (複雑なジェスチャー, 画像の比較)
  - AsyncTask 以外の非同期待ち合わせ (okHttp, Retrofit はダメ)

- Espresso Test Recorder の動かし方
  - Android Studio > Run > Record Espresso Test
  - あとは、端末で何かしらの操作を行うと、コード側にテストが増えていく

  - 直感的な操作でわかりやすい、が RecyclerView, ListView, Picker系, WebView は動作が怪しい
      - AsyncTask 以外のバックグラウンドスレッドを使っていると、巨大な Sleep が挿入されることがある


- 効率的にテストを書く
  - できるだけ、 Espresso Test Recorder が得意なテストケースを自動化対象にする
      - Espresso Test Recorder が対応しているコンポーネントが多いか
      - 対応していなくても手書きのテストで対応はできる
  - RecyclerView の view item 内の操作は、汎用メソッドを用意すれば対応可能

  - Espresso Test Recorder を使ったテストだと、コピペのようなテストが生成されてしまう問題
      - 同じような操作を繰り返していると、そうなってしまう
      - 対処:
          - テスト時に操作・確認する可能性があるものを一度だけ記録する
          - 動かない出力を修正する
          - 操作・検証単位でメソッドにする
              - Extract Method を使うと便利
          - 上記のメソッドのみを使って、手動でテストをかく
              - そのメソッドしか使ってないので、表示仕様の方が変わっても、そのメソッド一つだけを修正すれば OK になる

  - Espresso Test Recorder 出力で、動かない箇所の修正方法
      - 覚えておくと良い Android Studio のショートカット (Help > Find Action...)
          - Extract Variable
          - Extract Method
          - Inline
          - Move Line UP
          - Duplicate Line or Selection
          - Generate

      - RecyclerViewActions.actionOnItemAtPosition() は ItemView そのものしか操作できない問題
          - 例えば、 View の中にある, 子View の操作はできない
              - → これは独自実装で、ItemView の中の View を操作する形で対応



## 質疑応答

- Applium では Picker の扱いをどうするかで挫折したが、 Espresso はどうすれば良いか
  - PickerActions を使うと良い
  - https://developer.android.com/reference/android/support/test/espresso/contrib/PickerActions.html


# 講演8: 全てSになる〜RxJavaとLWSを持ち込む楽しさ〜

## 登壇者
- ryugoo さん (ChatWork)
- Twitter ID: [@ryugoo_](https://twitter.com/ryugoo_)
- [スライド](https://www.slideshare.net/ryugoo/s-rxjavalws)
- [サンプルアプリ](https://github.com/ryugoo/StreamDemo)

## 概要
- RxJava, Light Weight Stream API を使って簡潔にコードを書く方法を紹介

## 発表内容

- Java 8 の機能を Android アプリ開発時にも利用できるようにする

- [Retrolambda](https://github.com/evant/gradle-retrolambda)
  - Java 8 の Lambda 式を Android でできるようにする

- [RxJava](https://github.com/ReactiveX/RxJava)
  - Android API の痒いところ (非同期処理, イベント通知) を補ってくれる
  - Stream API のように機能する
  - 非同期・動機を意識せずに処理をかける
  
  - RxJava は他のライブラリとの相性が良い
      - [RxBinding](https://github.com/JakeWharton/RxBinding)
      - [RxAndroid](https://github.com/ReactiveX/RxAndroid)
      - [RxLifestyle](https://github.com/trello/RxLifecycle)

  - RxJava で、非同期処理を AsyncTask で書くよりも簡潔にかける
      - RxAndroid を利用すると、結果を通知するスレッドを指定できる
      - RxBinding を利用すると、クリックイベントを RxJava でハンドリングできる
          - ボタンがタップされたのをトリガーにして、WebAPI と通信する、といった処理を書くときに便利

- [Lightweight-Stream-API](https://github.com/aNNiMON/Lightweight-Stream-API)
  - Stream API:
      - コレクション操作に特化した API
      - RxJava にもあるが、より専門的
  - Optional API
      - 値がないかもしれないことを表現できる
      - NullPointerException と戦いたいときに
      - ifPresent
          - 通常の if で null チェックするよりも強力
          - ifPresent で値があったら、処理を行って、それを次のメソッドチェーンで処理して... といったことがかけるので
      - FragmentManager から Fragment を取得する処理とかは、かなり短く書ける印象
  - Exceptional API

- RxJava + Lightweight-Stream-API という組み合わせをする例
  - エラーハンドリング問題
      - RxJava で exception を投げると、 onError に Throwable 投げて購読が終了する
          - → こうなると、WebAPI のリクエストに失敗したら、ユーザがもう一度リトライしようとしても何も反応しない、という感じになってしまう
          - 対処としては, Either タイプを使って通信の失敗を通知する
              - 想定内の失敗、想定外の失敗を分けて処理できる
              - 想定内の失敗、ということで処理できると、購読が終了させないで住むようにする


##



# 講演9: 少し幸せになる技術

## 登壇者
- kamedonさん (クラスメソッド)
- Twitter ID: [@kamedon39](https://twitter.com/kamedon39)

## 概要

- 初心者〜中級者向けに、 Android開発をもっと楽にする方法、開発でつまづきそうなこと、アカウント停止されないようにする方法を紹介

## 発表内容

- AndroidStudio
  - ショートカット:
      - Find Action: Android Studio にどんなコマンドがあるか検索できる
      - Search Everywhere: ファイル名の検索ができる
  - アンインストール, インストールが面倒:
      - ADB Idea プラグインを使うことで、簡単な手順で端末内アプリのインストール/アンインストールが可能


- Build.gradle
  - 開発版とリリース版を共存させる方法
      - BuildVariant, ProductFlavor を使うことができる
      - 開発版とリリース版で パッケージ名が変わるように Suffix をつけると良い
          - applicationIdSuffix
  - 開発版とリリース版で定数を分けたい
      - WebAPI にて開発版とリリース版で異なるエンドポイントを設定したいとき
      - BuildConfig ファイルでできる
          - buildConfigField
  - 開発版とリリース版どちらかをわかりやすくしたい
      - ビルドバリアント/フレーバー毎にリソースファイル・ソースコードを異なるフォルダに分けることで可能
          - src/demoDebug/ (ビルドバリアントフレーバー)
          - src/debug/ (ビルドバリアント)
          - src/demo/ (フレーバー)
          - src/mail/ (メイン)
      - デバッグ版のアプリについて、アプリ名/アイコンをリリース版と異なるようにすれば良い

      - 使い分け
          - ビルドバリアント: 環境の設定
              - サーバのアドレス
              - 署名
    
          - プロダクトフレーバー: アプリの振る舞い
              - デバッグモード
              - 課金

  - バージョンコードとバージョン名管理が面倒
      - 以下でやると良い
      
          ```
          versionCode major * 10000 + minor * 1000 + patch
          versionName "${major}.${minor}.${patch}"
          ```
          
      - リリース番号が変わると、それに応じてバージョンコードも変わる

  - 署名情報を
      - 方法1: build.gradle にベタがき
          - private リポジトリなら github にコミットしても良い (漏れない前提)
      
      - 方法2: 署名情報をファイルに書き出す
          - keystore.properties とかに署名情報を書き出し、 build.gradle で読み込む
          - .gitignore とかに書いて、コミットはされないようにする

- デバッグ
  - 製品版の時は Log を出したくない
      - Timber を使う
          - Debug だけログを出すことができる
          
  - ネットワーク通信のデバッグ
      - 開発中のアプリのデバッグ: stetho を使う
      - リリースしたアプリのデバッグ: mitmproxy を使う
      
  - メモリリークのデバッグ
      - leakcanary を使う

  - Log のせいでテストが通らない
      - Log だけなら ClassLoader の仕組みを使って何もさせないようにする処理に上書きする

  - ProGuard
      - アプリサイズの削減
      - 難読化
  
  - メソッド数が 64k 個までの制限がある
      - 対処
          - ProGuard してメソッド数削減する
          - Multidex化する
    
  - ProGuard かけるとエラーになる
      - メソッドが削除/名前が変わっているのが原因。 keep させると良い
  
  - クラッシュレポートが難読化されている
      - mapping.txt を GooglePlayConsole にアップロードする


- GooglePlay
  - 最近、デベロッパーポリシーが変わったので確認しましょう
      - 広告のポリシー
  - いつ公開されるのか知りたい
      - 公開されたら通知されるように設定することができる