Androidの基本のキ！！！compileSdk・targetSdk・minSdkをざっくりまとめて理解する

# はじめに

中古のAndroidスマートフォンを調べていたのですが、安価で買えるのがどれも2017年や2018年に販売された端末でAndroid 8.0などのOSがデフォルトでインストールされているものがほとんどだったりします。

そこで開発中のアプリがそれらの中古スマートフォンで正しく動作してくれるのかを調べていくと`compileSdk`や`targetSdk`、それに`minSdk`などの設定が大事だとわかりました。
今まで、ふんわりとした意識で使っていたこれらの設定を改めて調べて、まとめて自分の忘備録として使用しようと思いこの記事を書きました。

あくまで忘備録として書かれているということを意識しながら読んでいただくと幸いです。

# Android SDKとは

AndroidSDKはGoogleが開発したAndroidプラットフォーム用のソフトウェア開発キットです。

AndroidSDKには、Androidアプリの開発に必要な開発ツールやテストのために必要な全てーのツール及びライブラリがコンポーネントという形で含まれています。

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/828ebc30-fd8c-47f4-f765-ac3388e5d8bd.png)

Androidの新しいバージョンやアップデートがリリースされるたびに、それに対応したAndroid SDKの新しいバージョンも公開されています。


## Android SDK Build-Tools

Android SDK Build-Toolsは、AndroidSDKに含まれているコンポーネントの一つです。

Android SDK Build-Toolsは、Androidアプリをビルドするために必要なAndroid SDKのコンポーネントです。


## Android SDK Platform Tools

Android SDK Platform-Toolsは、AndroidSDKに含まれているコンポーネントの一つです。

Android SDK Platform-Toolsには、主に**adb**や**fastboot**などのAndroidプラットフォームとのインターフェースとなるツールが含まれています。

# SDK Platformとは

SDK PlatformとはAndroid StudioのSDK Managerからダウンロード可能な、SDKパッケージのことです。

これはAndroid 13やAndroid 12といった、各バージョンごとにダウンロード可能なパッケージです。

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/92c846bb-88cd-a4de-e601-9d1aea4d2f4f.png)

そして、このパッケージには**Android SDK Platform パッケージ**、**System Image パッケージ**、**Sources for Android** パッケージが含まれています。

特に注意が必要なのが、`compileSDK`に指定されたAPI レベルと対応する**SDK Platform**がダウンロードされていない場合です。ビルド時にエラーが発生してビルドできなくなってしまうので、注意が必要です。

なぜかというと、SDK Platformに含まれているAndroid SDK Platformパッケージが各バージョン用にアプリをコンパイルする際に必要なパッケージだからです。

https://developer.android.com/studio/releases/platforms?hl=ja

# API レベルとは

API レベルとは、Android 13やAndroid 12といった各バージョンごとに提供されるAndrdoi SDKなどのフレームワーク APIと呼ばれるもののリビジョン（更新）を、それぞれ識別するために用いられる整数の値のことです。

例えば、Android1.0からAndroid2.0までに、API レベルの値は1から5に変化しています。これはAndroid1.0から2.0になるまでに**1.1**、**1.5**、**1.6**といったマイナーアップデートを挟んでいるためその度にリビジョンが更新されるのでAPI レベルもその分更新されたことを意味します。

https://developer.android.com/guide/topics/manifest/uses-sdk-element?hl=ja#ApiLevels

# compileSdkとは


`compileSdk`は、アプリをコンパイルする際にgradleによって使われるAndroid SDKのバージョンを表します。


`compileSdk`に指定したAPI レベル以下のAPIにて提供されている機能も利用可能なため、新しい機能はもちろんのこと、古い機能もそのまま使えることを意味しています。したがって、この値は常に最新のAPI レベルを指定して良いということです。


## compileSdkとtargetSdkの組み合わせは何を意味しているのか

次の文章を見つけました。

> Both compileSdkVersion and targetSdkVersion are crucial to handle forward compatibility in Android - so they both are connected with what to do when the new Android SDK version appears.

https://proandroiddev.com/compilesdkversion-and-targetsdkversion-what-is-the-difference-b4227c663ba8

つまり、`compileSdk`と`targetSdk`の値は前方互換性を処理する場合にとても重要な値ということであり、新しいバージョンのAndroid SDKが登場した時にどうすべきかということを意味しています。


# minSdkとは

`minSdk`は、アプリが動作するのを保証する下限のAPI レベルを表します。
Google Play Storeにおいては、ユーザーのデバイスが`minSdk`に指定されているAPI レベルを保証していて、動作可能かを確認する目的で使用されます。

そして、`minSdk`を指定する際は、アプリが依存しているライブラリの`minSdk`の値に強く影響を受けます。依存しているライブラリがアプリの`minSdk`に指定されている値よりも大きい場合には、そのライブラリの`minSdk`の値に追随させる必要があります。

そして、複数のライブラリに依存していて、各ライブラリの`minSdk`の値がバラバラの場合は、一番高い`minSdk`の値と少なくとも同じ値かそれより上の`minSdk`を指定することが推奨されています。

もし、依存しているライブラリの`minSdk`よりも低い`minSdk`を指定しないといけない場合は、徹底的にエラーが出ないようにテストなどを行い動作を保証する必要があります。

新しい`API`でしか提供されていない機能を`minSdk`で指定したAPI レベルで使用するのを防ぐためには、実行時にシステムのAPI レベルを確認して動作の可否を決定するという手法が広く利用されています。
また、`lint`を使うことで`minSdk`を超えるAPIを使用している際に警告を出すことができるので、互換性に関する問題を回避することができるようになっています。

おいしい健康さんの記事に面白い記述がありました。

> おいしい健康はリリース以降、minSDK 21だったので、Android L(5)の端末まで後方互換性がある状態でした。

https://oishi-kenko.hatenablog.com/entry/2022/08/03/133930

つまり、minSDKの値が小さいとその分サポート対象の端末が増えるという意味になります。

> 新しいライブラリを導入する時にもminSDKの要件を意識する必要があります。現状は導入したいライブラリがminSDK >= 21であることが多かったので、ブロッカーになることはありませんでしたが、今後要件が上がっていく可能性はあります。

https://oishi-kenko.hatenablog.com/entry/2022/08/03/133930

そして依存しているライブラリによっては、minSDKが開発しているアプリのminSDKの値より上の場合は要件を満たせなくなるため、API レベルを上げる必要が出てくることも意味しています。

# targetSdkとは

`targetSdk`を使うことでAndroidでは前方互換性の維持を行なっています。
つまり、`compileSdk`のAPI レベルが上がったとしても、`targetSdk`を更新しなければ動作に対する新しい変更を適用しないため、前方互換性を維持することができるという仕組みをAndroidでは提供しているのです。

そして、`targetSdk`は開発中のアプリがメインターゲットにしているSdkのバージョンを表します。
つまり、このSdkのバージョンで動くことを目標に開発されているということを意味していて、かつアプリにとってこの`targetSdk`で指定されたAPI レベルが最適なAndroid SDKのバージョンであり、正しく動きますよということをシステムに伝えるためのAPI レベルを表します。

もちろん端末のAndroidのAPI レベルが、それより上であろうが、それより下の値であろうが動く可能性はあるが、この`targetSdk`で指定されているAPI レベルが一番最適ですよということを表します。

特に、Google Play Storeのような市場では、`targetSdk`のAPI レベルによって最新の状態を表すことで、このアプリがどのくらいモダンであり最新の機能をサポートしているのかを表現しています。

# compileSdkとtargetSdkに指定する値の理想

`targetSdk`は`compileSdk`よりも大きな値を指定することはできません。
そして、`targetSdk`と`compileSdk`は同じAPI レベルを表していて、両方とも最新の値を指定することが望ましいとされています。

# targetSdkよりも新しいAPI レベルのバージョンを表すAndroidがインストールされている端末でアプリを実行した場合

設定された`targetSdk`よりも新しいAPI レベルのバージョンのAndroidがインストールされた端末でアプリをユーザーが実行した場合、Androidは`targetSdk`で指定されたAPI レベルとの後方互換性を維持しアプリの動作を保証するために、UIにおける新しい見た目や動作などを`targetSdk`で動作するものに置き換えたりする可能性があります。

# Android SDKの新しいバージョンでのみ提供されている新しいAPIを使いたい場合

`targetSdk`はアプリがどのAndroidバージョン向けに設計とテストがされたかをAndroidシステムに伝えるためのプロパティとして使われています。

そして、アプリから最新のAPIにアクセスできるようにするためには、`compileSdk`の値をそのAPI レベルにアップデートする必要があります。
これにより、Android StudioでそのAPIに関する新しいプロパティやメソッドにアクセスすることが可能となります。

しかし、この時`minSdk`の値が`compileSdk`の値よりも低い場合には、古いバージョンの端末では新しいSDKで公開されたAPIにアクセスできないので対処する必要があります。例えば、実行時にシステムのAPI レベルを確認して、動作の可否を検証するなどの手法です。

そして逆に、新しいAndroid SDKでは、従来提供されていたAPIが**Deplicated**になっていたりコンパイル時に警告やエラーが発生する可能性があるので、こちらもまた対処する必要があります。

実際に`comileSdk`で指定したAPI レベルで提供されている新しいAPIをアプリで使えるようにするためには、`targetSdk`を変更して`compileSdk`と同じ値にする必要があります。

この変更によりAndroidのシステムはアプリが新しいAPIにアクセスできることを知ることができるのです。

# 各種sdkバージョンの意味のまとめ

| 種類 | 主な意味 |
| --- | --- |
|  compileSdk   |   基本的には常に最新のAPI レベル |
|  targetSdk    |   アプリが一番快適に動くことが期待されている現在地のAPI レベル（理想的に言えば、compileSdkと同じ値が望ましい）  |
|  minSdk       |   アプリがサポートする一番古いAPI レベル  |

# まとめ

普段はなんとなく設定している**build.gradle**の`compileSdk`、`targetSdk`そして`minSdk`。しかし改めて調べてみると、当然ですがそれぞれに役割や意味があり互換性を維持するために重要な役割を果たしていることがわかりました。

改めて調べてみることで、ふわっとなっていたそれぞれのバージョンに対するイメージが、より鮮明になった気がします。


# 参考にした記事

https://developer.android.com/studio/releases/build-tools

https://developer.android.com/studio/releases/platform-tools

https://qiita.com/takahirom/items/e00126586c13aebf1a6b#targetsdkversion

https://qiita.com/uhooi/items/0f2ad61d83b96d9166c8

https://stackoverflow.com/questions/24510219/what-is-the-difference-between-min-sdk-version-target-sdk-version-vs-compile-sd

https://proandroiddev.com/compilesdkversion-and-targetsdkversion-what-is-the-difference-b4227c663ba8

https://medium.com/androiddevelopers/picking-your-compilesdkversion-minsdkversion-targetsdkversion-a098a0341ebd

https://stackoverflow.com/questions/24510219/what-is-the-difference-between-min-sdk-version-target-sdk-version-vs-compile-sd