スポンサーリンク

2016年9月22日木曜日

Android アプリの後方互換性と前方互換性

Android アプリの互換性

Android アプリには後方互換性(backward compatibility)と前方互換性(forward compatibility)が保証されています。

これらの互換性は build.gradle の中の以下のパラメータで制御されます。

  • compileSdkVersion
  • minSdkVersion
  • targetSdkVersion

これらは使用可能な API レベルや互換性をコントロールする重要なパラメータですが、意外にも正確なところがあまり理解されていないようです。 なのでこれらのパラメータを整理してみました。


compileSdkVersion

compileSdkVersion は Gradle に対し、どの SDK を使うかを指示します。ビルド時のみ参照されるパラメータです。

SDK のアップデートで追加された新しい API を使いたい場合、compileSdkVersion を更新します。

意外と知られていない様ですが、compileSdkVersion を変更してもアプリの動作は一切変化しません。これは重要な点です。

但し SDK のアップデートによりエラーチェックが厳密になり、今まで何も無かったところに警告やエラーが出たり、非推奨になった API の使用に警告が出ることはあります。当然これらは何らかの対策をすべきです。

compileSdkVersion は名前からして、変更するとアプリの動作が変わってしまうのではないかと、アップデートすることに以前は強い抵抗感がありましたが、その心配はありません。基本的には常に最新 SDK バージョンを指すようにすることが推奨されています。

また、サポートライブラリを使う場合は、compileSdkVersion とメジャーバージョンが同じライブラリを使う必要があります。そうしないと以下のような警告が出ます。

minSdkVersion

minSdkVersion は後方互換性(backword compatibility)の限界値を示すパラメータです。警告等を適切に処理したアプリであれば、この値以上の Android バージョンのデバイスで正しく実行することができます。

minSdkVersion は Google Play Store に対して、どのデバイスでインストール可能にするかを伝える役割も果たします。

また開発時に、Lint もこのパラメータを使用します。minSdkVersion で指定したデバイスに存在しない API を使おうとした場合エラー出してくれます。これにより、実行時に存在しない API を呼び出してクラッシュしてしまうことを回避できます。

注意点は、サポートライブラリやその他のライブラリを使う場合、それぞれのライブラリが独自に minSdkVersion を持っていることがあります。なので、アプリで指定するバージョンは、依存するライブラリの minSdkVersion と同じかそれ以上でなくてはなりません。

どうしてもそれより低い minSdkVersion を使いたい場合は AndroidManifest.xml の中で tools:overrideLibrary アトリビュートを使えばできないことはありません。その場合、Java コードの中でバージョンによって処理を切り替える実装が必要になるでしょう。

targetSdkVersion

一番分かりにくいのが targetSdkVersion です。どうも、動作が保証される Android バージョンの上限値と思い込んでいる人が多いようですが、これは間違いです。

上で compileSdkVersion は変更しても動作が変わらないと述べました。それに対し、この targetSdkVersion は、変更するとアプリの動作が変わる可能性があります。例えば、targetSdkVersion を23以上にすると、runtime permission model が有効になり、Android 6.0 以上で実行した場合に実行時パーミッションの処理が必要になります。

しかし逆に言うと、targetSdkVersion を変えない限りアプリの動作は変化しないので、compilseSdkVersion だけをアップデートすることにより、アプリに影響せずに新しい API を使用できます。

また、targetSdkVersion よりも高い Android バージョンのデバイスで実行しても、動作の互換性が保証されます。これが前方互換性(forward compatibility)です。

targetSdkVersion は原則的には自分の目的に合ったものを選択する必要があります。そのためにはどのバージョンがどんな特徴を持つかを把握しなくてはなりません。基本情報は ここ にありますが、こんなもの見てもさっぱり分からないでしょう。なので例えば Android 6.0 であれば、ここ を見たりして詳細を知る必要がります。しかし実際には、とりあえずはその時点での最新の API レベルを指すようにして、問題があれば調整する、というのが現実的ではないでしょうか。

公式ドキュメント でも、Android のバージョンアップに合わせてアプリを成長させるには、targetSdkVersion も最新の API レベルに合わせて更新することを推奨しています。そのためには、当然ながら常にターゲットバージョンで慎重に、かつ十分にテストする必要があります。

サポートライブラリを使う場合、サポートライブラリのバージョンは targetSdkVersion 以上である必要があります。

各SDKバージョンの関係

compileSdkVersion はコンパイル時のみに参照されるパラメータです。それに対し、minSdkVersion と targetSdkVersion は apk の中に埋め込まれます。

build.gradle の記述方法を見てみましょう。

android {
  compileSdkVersion 23
  buildToolsVersion "23.0.1"

  defaultConfig {
    applicationId "com.android.example.testapp"

    minSdkVersion 9
    targetSdkVersion 23

    versionCode 1
    versionName "1.0"
  }
}

compileSdkVersion は、buildToolsVersion と共に、 android { ... } の直下に記述します。それに対し、minSdkVersion と targetSdkVersion は defaultConfig { ... } の中に記述します。defaultConfig は build variant の一種ですが、全ての build variant のベースとなるものです。

三つのパラメータの関係は、

minSdkVersion <= targetSdkVersion <= compileSdkVersion

となります。

理想的には、minSdkVersion は可能な限り低いバージョンを指定し、compileSdkVersion と targetSdkVersion はどちらもその時点での SDK の最新を設定するのがよいでしょう。


参照ページ
https://medium.com/google-developers/picking-your-compilesdkversion-minsdkversion-targetsdkversion-a098a0341ebd#.9igya6j4r
https://developer.android.com/guide/topics/manifest/uses-sdk-element.html

0 件のコメント :

コメントを投稿