ライブラリのtargetSdkVersionは何を宣言するべきか

この記事をシェア

Android 14がリリースされ、アプリのAPI Level 34への対応が急がれる今日この頃ですが、ライブラリのtargetSdkVersionもアプリと同じように更新すべきなのか、分からなかったので調べました。この記事では、ライブラリのtargetSdkVersionが、そのライブラリを利用するアプリに与える影響を説明し、ライブラリのtargetSdkVersionに何を宣言すべきかを説明します。

いきなり結論

調べた結果、私としては以下の結論に到達しました。

  • ライブラリのtargetSdkVersionは、16以上であれば何でもいい

ここからは調べたことを順を追って説明していきます。なお、この記事に書いてあることは基本的にdevelopers.android.comに説明がありますので、オリジナルソースを確認したい人はそちらをご覧ください。

Manifestはマージされる

targetSdkVersionはManifestで宣言されますが、Androidではアプリ本体(以下、メインと呼びます)とライブラリそれぞれがManifestを持っています。場合によっては、これらに加えてビルドバリアント毎のManifestが存在する場合もあります。これらの複数のManifestは、ビルド時に一つのManifestにマージされます。

https://developer.android.com/build/manage-manifests#merge_priorities

Manifestの優先度は、高い順に、

  1. ビルドバリアント
  2. メイン
  3. ライブラリ

となっています。ライブラリのManifestは一番優先度が低いです。

優先度の高いManifestのtargetSdkVersionが採用される

Manifestで宣言されている各種パラメータは、それぞれルールに則ってマージされます。

複数のManifestに異なるtargetSdkVersionが宣言されている場合、優先度の高いManifestのtargetSdkVersionが採用されます。ライブラリのManifestは優先度が一番低いので、ライブラリのtargetSdkVersionの値が、マージ後のManifestのtargetSdkVersionの値として使われることはありません。

ここまでで、ライブラリのtargetSdkVersionは何でもよいのでは?どうせ使われないんでしょ?と考えたくなりますが、ひとつ注意事項があります。

権限が自動的に追加される場合がある

メインとライブラリそれぞれに異なるtargetSdkVersionが指定されている場合、条件によってはビルド後のアプリに自動的に権限が追加される場合があるという点に注意が必要です。

その条件は下記のとおりです。

  • ライブラリのtargetSdkVersionをX、メインのtargetSdkVersionをYとする。(ただし、X < Y)
  • API Level = Xでは不要だったが、API Level Yでは権限が必要なAPIがある場合、その権限が自動的に追加される

この挙動は、ライブラリが正常に動作するためのものです。ライブラリが古いtargetSdkVersionで実装されている場合、その当時は不要だった権限がその後のtargetSdkVersionでは必須になることがあります。その場合、ライブラリが正常に動作できないかもしれないので、ビルド時に自動的に権限を付与することで、権限不足によりアプリが動作しなくなることを防いでいます。

この条件だけみると、たくさんの権限が当てはまりそうに思います。しかし、developers.android.comによると、自動的に追加される権限は4つだけで、影響が出るのはtargetSdkVersionが15より小さい場合に限られるようです。

https://developer.android.com/build/manage-manifests#implicit_system_permissions

試してみる

私が公開しているZoomableというライブラリと、そのサンプルアプリで実験してみました。

ライブラリのtargetSdkVersionを変えて、ビルド後のマージされたManifestを比較してみます。左が、ライブラリ・メインともにtargetSdkVersionが34の場合です。右が、ライブラリのtargetSdkVersionを3にした場合です。

ライブラリのtargetSdkVersionが3の場合には、WRITE_EXTERNAL_STORAGEなどの権限が追加されていることが確認できます。また、どちらもマージ後のtargetSdkVersionは34となっており、メインのtargetSdkVersionが優先されていることが確認できます。

まとめ

ライブラリのtargetSdkVersionは、マージ後のManifestにその値が反映されないため、細かいバージョンは気にする必要がないことが分かりました。しかしあまりに古いバージョンを指定していると、不要な権限が自動的に追加されてしまう場合があるので、16以上を指定すべきです。

もちろん、targetSdkVersionによって挙動が変わるようなライブラリなら、いろいろ考慮した上でバージョンを決定することになると思いますが、そうではない場合は、あまり深く考えずにcompileSdkVersionを更新するときにtargetSdkVersionもまとめて更新しておく、くらいの認識で良さそうです。

この記事をシェア