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

Androidアプリをいつまでも楽しく開発し続けるための取り組み

 Androidアプリをいつまでも楽しく開発し続けるための取り組み

こやまカニ大好き

February 13, 2020
Tweet

More Decks by こやまカニ大好き

Other Decks in Programming

Transcript

  1. Androidアプリをいつまでも楽しく開発
    し続けるための取り組み
    Cookpad.apk #4

    View Slide

  2. 自己紹介
    こやまカニ大好き(@nein37)
    モバイル基盤部所属
    社内全Androidプロジェクトの開発効率化と技術サポート
    minSdkVersion 上げたりモジュール分割したりしてます
    2

    View Slide

  3. android-cookpad アプリのこ
    れまでの歩み
    3

    View Slide

  4. 2012年にAndroidアプリをリリース
    ● 一つのチームでアプリを開発
    ● 当初はほぼWebViewで構成されたアプリ
    ○ コンテンツの更新や新機能をすばやくユーザーに提供することを目的としていた
    ○ 探すと当時のインタビュー記事が出てくる
    ○ https://el.jibun.atmarkit.co.jp/rails/2012/10/html5-d1ba.html
    ● JavascriptInterface を利用
    ○ Javascript からネイティブ実装を呼び出すための仕組み
    ○ この時入った仕組みの一部はいまだにクックパッドアプリで利用されている
    ● 課題 : WebViewによるテスト、不具合検知の難しさ
    4

    View Slide

  5. 2014年にフルリニューアル
    ● ネイティブアプリとしてリニューアル
    ● ネイティブ実装によるユーザー体験の向上、メンテナンス性の向上
    ● 当時は Android Developers の実装ガイドなどが充実していなかったため、
    書いた時期や開発者によって実装スタイルがバラバラ
    ● このころまでは一つのチームで開発を行っていた
    ● 課題 : いつ/どの機能がリリースされるのか周知することが難しい
    5

    View Slide

  6. モバイル基盤誕生
    ● 各部署のメンバーが担当する機能の開発を行う方式へ
    ● CI整備やリリース作業などどの部署にも属さない役割のカバーや全体的な効率
    化のためにモバイル基盤グループが誕生
    ● アプリの状態監視や各機能のバグ修正も行っていた
    ● 課題 : リリースごとに各部署の調整が必要になっていて高コスト
    6

    View Slide

  7. フルリニューアル後リリースフローを整備
    ● アプリの運用ルールを整備 
    ○ 2週間毎のリリース
    ○ 開発・テスト・リリース後監視フローの整理
    ○ リリーマネージャ・監視の手順化・持ち回り
    ● 課題:各施策・各部署の連携と開発リソース調整
    7

    View Slide

  8. モバイル基盤の役割の明確化
    ● モバイル開発に関する課題を解決する部署へ
    ● バグ調査やリリースまわりの調整から開発しやすさの向上へ
    ● Danger などのコードレビュー負荷軽減
    ● CI・開発環境の改善
    ● ビルド時間の計測・改善に向けた努力
    ● リリースに関する負荷の軽減
    8

    View Slide

  9. 楽しいAndroid開発#とは
    9

    View Slide

  10. Androidアプリの開発
    ● ユーザーに価値を届けるための開発
    ● 最小のコストで機能開発/バグ修正を行う
    ● 最小のコストでユーザーの手元に届ける
    ● コスト=時間+手間
    10

    View Slide

  11. 時間がかかると楽しくない
    ● ビルド時間が長い
    ● CIの待ち時間が長い
    ● 変更がマージされてから
    リリースまでの時間が長い
    11

    View Slide

  12. ● コードをどこに書けば良いのかわからない
    ● コードをどう書けば良いのかわからない
    ● 認証処理・ユーザー状態の判定が難しい
    ● 古いJavaコード触りたくない
    ● 意味不明なビルドバリアント
    手間がかかると楽しくない
    12

    View Slide

  13. モバイル基盤部の役割
    ● 時間と手間を最小限にするために取り組む
    ● アプリ開発を魅力的なものにする
    ● ユーザーに新しい価値を
    素早く届けられるようにする
    ● モバイル基盤部の目標にも「生産性について」
    という項目があり、機能開発にかかる時間を
    最小化することを明確に目標にしている
    13

    View Slide

  14. 実際の取り組み(時間)
    14

    View Slide

  15. ビルド時間の削減
    ● ビルドの時間が遅いと全てが遅いので優先度は高い
    ● まずは測定するところから始める
    ○ ビルド時間を可視化できると成果がでたときにも嬉しい
    ● 差分ビルド時間の最小化にフォーカスする
    ○ 開発者の手元の作業によって大きく変動するので細かい数値は追わないほうが良い
    ○ 一定期間の傾向としての増減で見ている
    15

    View Slide

  16. ビルド時間の削減
    ● ビルド時間を短くするためにできることは公式に書いてある
    ○ https://developer.android.com/studio/build/optimize-your-build
    ● モジュールを分割してキャッシュを有効利用する
    ○ Gradleキャッシュへの理解を深める
    ● Apply Changes がまともに動くようにする
    ○ https://developer.android.com/studio/run#apply-changes
    ○ 使えない場面のほうが多いが使えたほうが良い場面はもちろんある
    ○ debug build variant がまともに動くようにする
    16

    View Slide

  17. ビルド時間の削減
    ● minSdkVersion を上げる
    ○ 過去のOSバージョンをサポートするためにやっている処理が不要になるビルド時間を短縮
    ○ 特に minSdkVersion 21 未満の場合に有効
    17

    View Slide

  18. ビルド時間の削減
    ● PCのスペックを上げる
    ○ モバイル開発者は全員 MacBook Pro
    ○ CPU 2.4GHz 8コア/RAM 32GB
    ○ 実際の計測結果などを Gradle build scan で
    記録に残しつつ必要スペックを決めている
    ○ 検証手順もきちんと残す
    18

    View Slide

  19. ビルド時間の削減
    ● ビルド時間の改善は影響の大きそうなところから崩していく
    ● 後はひたすらモジュール分割とGradle/Gradle Plugin の改善についていく
    ● アプリの仕様やマシンの見直しも必要ならやっていく
    19

    View Slide

  20. CI待ち時間の改善
    ● 最近 CodeBuild に切り替えた
    ○ https://techlife.cookpad.com/entry/2020/01/30/100000
    ● CIビルド時間はまだ改善の余地がありそう
    ● ジョブの分割によって問題のある箇所がわかりやすくなった
    20

    View Slide

  21. リリース待ち時間の改善
    ● 毎週リリース
    ○ これまでは重要な施策がある場合そちらを優先して
    スケジュールを調整していたため、
    実際にリリースされるタイミングは不透明だった
    ○ https://techlife.cookpad.com/entry/2018/09/14/090000
    ● リリースフローの(半)自動化
    ● 問題発生時のフロー整備
    ○ 緊急リリースorリリーススキップの判断基準
    ○ 実際の緊急リリース作業のドキュメント化
    21

    View Slide

  22. 実際の取り組み(手間)
    22

    View Slide

  23. アーキテクチャ/コードベースの改善
    ● 無法状態(+若干のMVP) -> VIPER
    ○ 現在画面のおよそ35%がVIPER化されたコード
    ○ サンプルコードを含むドキュメントを整備
    ● 既存画面のVIPER化よりも共有コードの改善を優先
    ● Kotlin 化は昨年後半でかなり進み現在半分以上が Kotlin
    23

    View Slide

  24. レガシーコードの改善
    ● DIの(再)導入
    ○ 以前 Toothpick を導入していた
    ○ Toothpick のコード生成が失敗することがあった
    ○ (特に)シングルトンインスタンスの管理が分散
    ● KOINを導入
    ○ これまでのシングルトンインスタンス管理もすべて DIに寄せる
    ○ DIの利用方法・モジュール分割時の記述方法をドキュメント化
    ○ 新規のコードではKOINの利用を推奨(レビュー時の指摘/お手本PR)
    24

    View Slide

  25. レガシーコードの改善
    ● 認証・通信処理の改善
    ○ 最初は認証モジュール・通信モジュールで分離していた
    ○ 通信途中での再認証など特殊な処理が多いため、認証・通信モジュールにした
    ○ Kotlin の internal と組み合わせて可視性を最適化
    25

    View Slide

  26. レガシーコードの改善
    ● アプリケーション初期化処理の改善
    ○ ApplicationInitializer というクラスがアプリ内の初期化処理を行っていた
    ○ シングルトンインスタンスの初期化など処理順を意識する必要があった
    ○ 「depends on XXX」 という真偽不明のコメントにより触れない処理たち
    ● 初期化処理を KOIN で行えるものは KOIN で行う
    ● 無理なものはきちんとカテゴリごとに整理してこまかくコメント
    26

    View Slide

  27. レガシーコードの改善
    ● その他の取り組みなど
    ○ Cookpad.apk や 技術ブログで随時共有しています
    ○ https://techlife.cookpad.com/entry/2019/10/21/144205
    ○ https://techlife.cookpad.com/entry/2020/01/16/090000
    ○ https://cookpad.connpass.com/event/137772/
    27

    View Slide

  28. リリース デバッグ
    ビルドバリアントの整理
    ● モジュールによる設定解決
    ○ 接続先設定などのモジュール化
    ○ デバッグ機能のモジュール化
    ○ モジュールの依存解決によって
    アプリの設定・機能の切り替えを行う
    ● 実装方法は2種類
    ○ 同一パッケージ/同一クラスにコードを配置
    ○ インターフェイスを共通モジュールにおいて
    実装だけを切り替える
    28
    App_Release App_Debug
    Feature_Debug
    Feature_Release
    Settings_Release Settings_Debug
    Settings_Base
    Libraries
    Features

    View Slide

  29. まとめ
    29

    View Slide

  30. まとめ
    ● アプリ開発にかかる時間と手間を最小化することで
    楽しく開発を続けることができる
    ● クックパッドではモバイル基盤が業務として
    時間と手間を最小化に取り組んでいる
    ● これからも引き続きユーザーに価値を届けるための開発を
    サポートしていく
    30

    View Slide

  31. おまけ
    31

    View Slide

  32. minSdkVersion 23 のお知らせ
    ● クックパッドアプリでは3月からminSdkVersion を 23 にします
    ○ AppCompat v1.1.0 が 5.x 端末でクラッシュする問題
    ○ 5.x で `android:foreground` 使えない問題
    ○ Drawable への tint 適用時の挙動などが 5.x で異なる問題
    ○ Samsung 5.x 端末での kotlinx.coroutines クラッシュ問題 など
    32

    View Slide