👻

Android15へのバージョンアップ対応の振り返り

に公開

株式会社ココナラアプリ開発グループ、Androidチームの田松です。

今回は、ココナラAndroidアプリにおけるAndroid15へのバージョンアップ対応についてご紹介します。

背景

Android16が2025年6月にリリースされたことで、ココナラアプリもこれから対応していかなければなりません。またAndroid15への対応もココナラではつい2,3ヶ月程前に実施したばかりなので、このタイミングで振り返ることによってAndroid16への対応に向けた助走としたいと思います。

Android15の新機能や変更点

Android15の新機能や変更点については、公式ページに表としてまとめられています。

この表を元にココナラアプリで影響がありそうな部分を洗い出していくわけですが、細かなアップデートも多く、全てを紹介できないので、今回は大きな変更点となる以下2点をピックアップしてそれぞれ対応した内容や大変だった点を簡単にご紹介できればと思います。

  • Edge-to-Edge
  • 16KBページサイズ端末対応

Edge-to-Edgeへの対応

Edge-to-Edgeとは?

Edge-to-Edgeに対応するにあたって、そもそものEdge-to-Edgeについて簡単に説明したいと思います。

Edge-to-Edgeとは下図のように従来のステータスバー(上部帯)とナビゲーションバー(下部帯)部分に存在していた描画領域の境界を広げ、画面全体を活用することでUIに連続性を持たせ、ユーザにアプリへの没入感を提供するものです。

従来 Edge-to-Edge
before_edge_to_edge before_edge_to_edge

ココナラアプリへの適用

本来は広がった描画領域に新たなコンテンツを表示させることが機能の意図としては正しそうですが、今回は広がった描画領域に余白を持たせて既存とデザインがなるべく相違ないような形へ対応していきます。

基本的には公式で用意されている方法で余白を処理(インセットを処理すると言う)していきますが、ココナラアプリでは現在画面毎にAndroid ViewとフルComposeされたものが混在するため、ステータスバーやナビゲーションバー分の余白を持たせるにあたって、それぞれの方法で処理します。

  • Android View
    Android ViewではViewのルートにインセットリスナーをセットして、ステータスバーとナビゲーションバーの高さを取得し、paddingを設定します。
ViewCompat.setOnApplyWindowInsetsListener(
    findViewById(android.R.id.content),
) { v: View, insets: WindowInsetsCompat ->
    val bars =
        insets.getInsets(
            WindowInsetsCompat.Type.systemBars() or
                WindowInsetsCompat.Type.displayCutout(),
        )
    v.updatePadding(
        bottom = bars.bottom,
        top = bars.top,
        left = bars.left,
        right = bars.right,
    )
    WindowInsetsCompat.CONSUMED
}
  • Compose View
    ココナラアプリでは現状Material2を利用しているため、画面のルートComposableに以下を設定して適用します。
    Material3を利用していれば自動で処理してくれるComposableも存在するため、移行時には不要になるかもしれないので注意が必要です。
Modifier.safeDrawingPadding()



このように余白自体は簡単に処理することができますが、Edge-to-Edgeが自動的に適用されるのはAndroid15以降の端末なので、Android14以前の端末は明示的にEdge-to-Edgeを適用しなければ、OSバージョンによってデザインに差分ができてしまうので以下も各画面のActivityに合わせて記述します。

enableEdgeToEdge()

以上の対応によりOSバージョン間の差分をなくした上で、ステータスバーとナビゲーションバー部分の余白処理まで行えました。

余白処理前 処理後
before_insets after_insets

今回は割愛させていただきますが、ステータスバーやナビゲーションバーまで描画領域が広がったことによって、時計やシステムアイコン等が背景の色で潰れてしまうことがあるので、明示的にそれらを色指定する必要がある場合にも注意が必要です。

大変だった点

  • 適用範囲の広さ
    Edge-to-Edgeの適用や余白の処理自体は共通クラスに記述することである程度簡略化できましたが、全画面への適用という範囲の広さによる、各画面でのデザイン崩れや操作感に違和感がないかを検証する作業がとても大変でした。
  • ライブラリ側の処理との衝突
    ココナラアプリではBrazeというライブラリを利用してポップアップメッセージを表示させているのですが、このポップアップメッセージ表示時にココナラアプリ側でセットしているインセットリスナーを上書きしてしまい、本来想定していた挙動にならないということがありました。
    今回は幸いBrazeのソースが公開されているということもあり、ソースを読んで該当処理をカスタムする形で対応しました。

16KBページサイズ端末対応

16KBページサイズとは?

16KBページサイズとは端末側の仕様でメモリを管理する際の基本単位であるページが、従来の4KBから16KBに大きくなったことで大幅なパフォーマンス向上が見込めるといったものです。
以下Android Developer Blogから抜粋ですが、これだけパフォーマンス向上が見込めるそうです。

  • アプリの起動が高速化:さまざまなアプリで 3% ~ 30% の改善が見られます。
  • バッテリー使用量の改善:平均 4.5% の増加を実感いただけます。
  • カメラの起動が高速化:カメラの起動が 4.5% ~ 6.6% 高速化されます。
  • システムの起動が高速化: Android デバイスの起動が約 8% 高速化されます。

今回はネイティブコードに従来の4KBページサイズを前提としたハードコーディングが存在した場合はクラッシュしてしまう点と2025年11月1日までに対応が完了していなければココナラアプリのアップデートをPlay Storeに配信できなくなってしまうため、マストで対応しなければいけませんでした。

対応内容

ココナラアプリのプロダクトコードではネイティブコードを使用している箇所が存在しないため、ライブラリ側での使用箇所に絞って調査と対応をします。
今回の調査方法としてはAndroid Studioの機能であるAPK Analyzerを利用して出力されるライブラリのsoファイルとgradleのキャッシュで出力されるsoファイルを突合してライブラリを絞り、各ライブラリのリリースノートで16KBページサイズ対応の記述を確認して対象のライブラリをアップデートする形で対応します。

  • APK Analyzer
    Menu -> Build -> Analyze APK
  • gradleキャッシュファイル出力
    find ~/.gradle/caches/${gradle version} -name "*.so"

また、Play Console上でも対応が必要なライブラリが表示されてくれるので、こちらで確認するのが一番手っ取り早いかもしれません。

no_16kb_page_size

大変だった点

  • 検証端末の問題
    弊社に16KBページサイズの端末がなかったため、開発者オプションから16KBページサイズモードで端末を起動できる設定を利用することで検証機の役割としました。
    ただこの設定を利用するにはOEMブートローダーのロックを解除する必要があり注意が必要です。

  • 未対応ライブラリの存在
    対応が必要であったライブラリの16KBページサイズの対応バージョンが存在していなかったため、ベンダー窓口を介して更新してもらえるように連絡を取って対応してもらいましたが、対応が遅れていたらと思うと...間に合ってよかったです。

リリース時のリスク回避

リリースには常にリスクが付きものですが、中でもOSバージョンアップは特に注意が必要です。全ての端末を全てのパターンでテストできれば一番良いですが、それだといくら時間があっても足りません。
なので、以下をそれぞれ行うことでリリース前後の正常動作担保とリスクヘッジを行います。

  • 前述した公式ページの機能と変更点のリストからココナラアプリの動作に影響がありそうな箇所を抜粋し、テストケースを作成し実施(リリース前検証)
  • 段階リリースの利用(リリース後のリスクヘッジ)
    いきなり全ユーザへ公開してしまうとクリティカルな問題が発生した際に影響が大きくなりすぎるので、緩やかに伝播させることで早期問題検知と影響を抑えられるようにします。
  • 切り戻し用のアプリを事前に用意(リリース後のリスクヘッジ)
    ストアのアプリを更新するには現在のバージョンコードよりも上のバージョンで申請をしなくてはいけないため、問題を検知した場合にすぐ切り戻せるようバージョンコードのみを上げた対応前のアプリを事前に用意しておくことで、早急に問題があるバージョンの伝播を防ぎます。

※現在では完全公開済みのリリースをPlay Consoleから停止して最新バージョンの配布をストップする機能も存在するようなので、今後はこちらも活用できたらと思います。

まとめ

当たり前と言えば当たり前ですが、普段からライブラリが最新だとOSバージョンアップにフォーカスを当てられるので常日頃からライブラリの更新は確認していきたいですね。
また、リスク回避できるよう万が一問題が起きた場合の対応を事前に用意するといったことも大事だと思います。
想定外の挙動が発生することもあり得る作業になるので、問題が発生しないよう努めつつも発生した際にどう対応するかを事前に考えておくと精神衛生上良いと思いました。

対応内容についてはOSのバージョンアップされた機能によって変わってしまうので、事前調査及びリリース前検証や後の対応を今回得た教訓としてAndroid16への対応に活かしたいという締めでAndroid15へのバージョンアップ対応の振り返りとします。

ココナラでは、一緒に事業のグロースを推進していただける様々な領域のエンジニアを募集しています。
アプリ開発だけでなく、フロントエンド領域・バックエンド領域などでも積極的にエンジニア採用を行っています。少しでも興味を持たれた方がいましたら、エンジニア採用ページをご覧ください。

https://coconala.co.jp/recruit/engineer/

Discussion