🏭

[Android] compileSdk を上げるタイミングについて

2023/09/28に公開

導入

前の記事で Android 14 (API Level 34)は現状ベータリリースだが platform stability なので compileSdk を 34 に上げても大丈夫らしいと書いたのですが、理屈をよく分かっていなかったのですこし深堀りしました。

compileSdk

  • アプリのコンパイル時に使用する android.jar のバージョンを指定するもの
  • android.jar はそのバージョンでの Android SDK の API を定義する
  • android.jar は実装の無いスタブファイルであり、アプリ(apk)にバンドルされない。アプリの実行時には Android OS 側に配置されている Andriod SDK の実装が参照される [1]

platform stability

  • 2020年から導入された Android OS のリリースの状態
  • ベータリリース状態の次期OSの SDK / NDK の API が確定したことを意味する

つまり

API が確定するということは次期バージョンの android.jar が確定する ということであり、かつ android.jar は API定義のみで実装を含まない為「platform stability に達した時点で compileSdk を最新にしても問題ない」ということになります。

ただし、API の差分には追加だけなく変更・削除も含まれるため、アプリのコードの修正が必要になる可能性はあります。

API の差分具体例

実際に compileSdk を更新する際は、とにかく一旦アップデートしてしまい、Android Studio で警告・エラーが出たら対応という流れで十分かと思われますが、具体的なAPIの差分がどのようなものかは以下ページで確認できます。

疑問

  • 古い API でコンパイルしたアプリが新しい API で削除されたクラスを参照している場合、新しいOSでアプリを起動するとエラーになる?

    • 試しに API Level 33 で削除された android.webkit.WebSettings.setAppCacheEnabled(boolean) を呼び出すコードを compileSdk 32 でビルドし API 33 のエミュレータで実行してみると、エラーにはならなかった

    • おそらく OS側の実装には setAppCacheEnabled が残っている?

    • Android のポリシーとして前方互換性が重視されているそうなので、古い API でコンパイルしたアプリが新しいOSでも動くような配慮?はされている模様

  • 仮に API のメソッドの引数が変更された場合、新しい API でコンパイルしたら古いOS で動かなくなったりするのでは?

    • そういう場合、メソッドのオーバーロードで別の(同名の)メソッドの追加という形になり、今までのメソッドはそのまま残るので、既存のコードが動かなくなるということはなさそうです。 [2]
  • 追加された API を使ったら古いOS でエラーになるのでは?

    • エラーになるので if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.XXX) のようなコードで分岐させることになります。 [3]

おわりに

通常は CompileSdk と TargetSdk を同時に上げる感じでよいかと思いますが、CompileSdk は TargetSdk と比較して割とカジュアルに上げても問題なさそうなので、ライブラリに要求されたり、アップデートが大変なときに先んじて CompileSdk のみ上げるという選択はアリかと思いました。

参考

おまけ

そもそも新しい AndroidOS で既存のアプリがちゃんと動くか?に関しては以下ページを確認するのがよさそうです。

脚注
  1. 若干抽象的な表現なのは、apk には Java バイトコード(*.class)が変換された dex ファイルが入っていて、Android Runtime (ART) はアプリのインストール時に dex を oat (ネイティブコード)に変換しているらしいのですが、具体的に Android SDK の実装がどこにどういう形式で存在し、アプリから参照されるのかよくわからなかったためです... ↩︎

  2. 場合によっては既存のAPIが Deprecated になるパターンもあると思われますが、Deprecated なしでいきなり Removed になるパターンはなさそうでした。 ↩︎

  3. platform stability 状態で新しいAPIを使うのはリスクがゼロではないので、使っても大丈夫な API か検討・検証が必要かと思います ↩︎

Discussion