agri-note inside

ウォーターセル株式会社 スマート農業システム開発部のブログです。

AndroidX対応時期の目安を考える

こんにちは、開発部の中川@Nkznです。今回はAndroidの話をします。

Googleから提供されているAndroid拡張パッケージ、サポートライブラリの後継としてAndroidXが登場してから、1年半が経ちました。皆様の移行状況はいかがでしょうか。

恥ずかしながら、弊社では移行が進んでおりません。有名ライブラリがAndroidX対応やサポートライブラリ非対応を進めていくニュースを日々目にしながら、圧を感じているところです。

とは言っても「移行しなくても直ちに死ぬわけではないしなー。それよりはビジネス要件のほうが先だからなー」という気持ちもそれなりにあり、腰が重くなっているのが現状です。

しかしながら、AndroidXの導入時期にはひとつの目安があることに気が付きました。本記事では、サポートライブラリとAndroidXの特性を確認しながら、移行時期に目安がある理由について解説します。

サポートライブラリとは

まずは、サポートライブラリがどんなものだったのかをおさらいしておきましょう。

developer.android.com

サポートライブラリを使わない、素のままのAndroidの標準ライブラリでは、 compileSdkVersion に応じたAPIが利用できます。より新しいバージョンを指定してあれば、新しく追加されたクラスやメソッドを利用することができるわけです。

こうして作られたアプリは minSdkVersion で示されたバージョンまでなら、下のバージョンのAndroidでも起動される可能性があります。 minSdkVersioncompileSdkVersion より古い場合、「コード側では最新のAPIが使えるけれど、実際に動作するAndroidにはそのAPIが用意されていない」という状況になることでしょう。何の対処もしなければ、クラッシュを引き起こします。

これを回避するためには、古いバージョンのAndroidでは新しいAPIを実行しないようにしたり、代替処理を用意する必要があります。 Build.VERSION.SDK_INT で条件分岐する方法は、現在でも有効な方法ですね。

しかしながら、いちいち代替処理を用意するのは面倒ですし、どこのアプリでも ActivityFragment 等に対して行う代替処理の内容は、似たものになります。そのため、バージョンごとの条件分岐や代替処理を内包しつつ、見た目上は最新版の標準ライブラリと似たような使い方ができるようなラッパークラスを提供する目的で、サポートライブラリが生まれました。

途中から、標準ライブラリに載せると取り回しが悪くなりそうなUIライブラリもサポートライブラリとして提供されるようになったりして、当初の目的よりも広いものになりましたが、来歴としてはこんなところです。

サポートライブラリの課題

さて、サポートライブラリは、バージョニングについて少々特殊なルールを持っていました。

v24.y.z というバージョンのサポートライブラリは compileSdkVersion: 24 でビルドしなければならない」といったように、バージョンの一番上の数値と compileSdkVersion の値を合わせる必要があるのです。

何かの都合で片方を上げるときには、必ずもう片方も上げなければいけないというのは、メンテナンスコストを増やす要因になっていました。

これがアプリの内部だけで済む話ならよかったのですが、サードパーティ製のライブラリがサポートライブラリに依存している場合は、そちらのバージョンも考慮に入れなければならないケースもあり、やはり辛さに繋がっていました

また、これはセマンティックバージョニングに沿わない命名ルールなので、 yz の桁が上がるということが、何を表すのかも明確ではありませんでした。 z の桁が上がるときに機能追加が行われた記憶もあります(要出典)。

AndroidXの登場

サポートライブラリが抱えていた、バージョニングのわかりづらさ、依存関係の取り回しの悪さ等の課題を解決するために、後継として登場したのがAndroidXだというのが筆者の認識です。

developer.android.com

AndroidXは、セマンティックバージョニングを厳格に適用しつつ、 v1.0.0 から再スタートを切りました。

運用上の課題にフォーカスした後継として登場しているため、機能面での破壊的変更はありません。これはつまり、 v1.x.x はサポートライブラリと全く同じクラスやメソッドを持つことが保証されるということです。

移行手順のページでは、Android Studioでの自動移行の機能も紹介されており、かなりお膳立てしてもらえているという印象です。

たとえ手動で移行することになったとしても、基本的にはimport文を書き換えるだけで済みます。

AndroidX移行のデッドライン?

さて、移行作業そのものは難しくなさそうですが、実際に移行しても大丈夫でしょうか。Twitterを眺めていると、「手元で使っているライブラリがまだサポートライブラリにロックインしていて移行できない」といった意見も見かけます。現実はシュッと移行して終わりというわけにはいかないようです。

しかしながら、「そのうち変えればいい」とも言っていられない時期が迫ってきていることに気が付きました。

targetSdkVersionによるリリース制限

2018年から、Google Playにリリースできる targetSdkVersion に制限がかかるようになりました。

developer.android.com

対象APIレベルの要件のページにもある通り、毎年 targetSdkVersion を上げるのが、Google Playのルールになってきています。

APIレベルの要件 開始日
Android 8.0(API レベル 26)
  • 2018 年 8 月 1 日: 新規アプリで必要
  • 2018 年 11 月 1 日: アプリのアップデートに必要
Android 9(API レベル 28)
  • 2019 年 8 月 1 日: 新規アプリで必要
  • 2019 年 11 月 1 日: アプリのアップデートに必要

このまま順当にいけば、2020年の夏〜秋にはAndroid 10(APIレベル29)が必須になることが予想されます。

APIレベル29のためのサポートライブラリは出ない

それでは、ここでAndroidXのドキュメントを眺めてみましょう。

バージョン 28.0.0 がサポート ライブラリの最終リリースです。android.support ライブラリの今後のリリースはありません。

https://developer.android.com/jetpack/androidx

そう、 compileSdkVersion: 29 に対応するサポートライブラリは現れない のです。

運用ルール次第では、AndroidX対応をするまでリリースができなくなる

targetSdkVersioncompileSdkVersion を揃えて上げていく運用をしているチームでは、これは問題になります。具体的には、次の条件が競合します。

  • targetSdkVersion を29にしないとリリースができなくなる
  • サポートライブラリを使っている限りは compileSdkVersion を28までしか上げられない

より強い都合を持っているのはGoogle Play側の要件なので、この問題に遭遇した場合には「2020年の秋までにAndroidXに対応する」というのが順当な選択肢になるでしょう。

逃げ道はある

デッドラインという表現を使いましたが、おそらくそこまでマストなものではありません。

compileSdkVersion: 28 かつ targetSdkVersion: 29 といった組み合わせはできるはずなので、いったんこれでお茶を濁すという運用回避が現実的かもしれません。

そもそも両者を揃えるメリットはあるかという議論もあります*1。弊社でも現在は28で揃っていますが、少し前まではずれていました。この辺はチームごとの運用によって変わるはずですので、各チームで話し合いましょう。

まとめ

  • サポートライブラリの運用上の課題を解決するのがAndroidX(のv1)
  • 現代のGoogle Playでは targetSdkVersion を上げる強制力が強い
  • サポートライブラリを使う場合に選択できる compileSdkVersion はAPIレベル28まで
  • targetSdkVersioncompileSdkVersion を揃える運用をし続けたいなら、2020年秋までにAndroidX対応を終えましょう

結果的に、絶対に今すぐ取り組むべき理由はないという結論になりました。ただ、強制力は弱めとはいえ「2020年秋」という期限が見えたので、ビジネス上の問題やライブラリの相性問題がなければ、それまでに移行しておくのがいいのではないでしょうか。

追記:アンケート結果

実際に皆さんがどのくらいの意識で targetSdkVersioncompileSdkVersion を揃えたり揃えなかったりしているのか気になったので、意識調査をしてみました。

特に理由がなければ揃えるけれど、現実にはうまくいかないこともある、くらいの結果になったかなと思います。