Support Library を ver23.1.0 から 23.3.0 にアップデートするときにやったこと


Support Library の ver23.2.0 では、かなり大きな機能追加がありました。詳しくは、 Android Developers Blog の投稿を参照ください。

- [Android Support Library 23.2（英語）](http://android-developers.blogspot.jp/2016/02/android-support-library-232.html)
- [Android Support Library 23.2（日本語）](http://googledevjp.blogspot.jp/2016/03/android-support-library-232.html)

とりわけ Android SDK 側で Vector Drawable のサポートが加わったことによって、最新の Support Library を導入したいと思う人は多いかと思います。

2016年4月15日時点で、Support Library の最新バージョンは 23.3.0 になります。この記事では [弊社Zaimアプリ](https://play.google.com/store/apps/details?id=net.zaim.android) で、23.1.0 からアップデートしたときに実際に行った作業を紹介していきたいと思います。

ただし、あくまで弊社の場合ですので Support Library の利用状況によっては、今回取り上げる内容以外にも対応が必要になるケースもあると思いますので、ご了承ください。

## やったことリスト

1. Support Library のバージョンを一括で管理するよう修正
2. Support Test の runner や espresso が依存する support-annotations を除外
3. TabLayout で新たに deprecated になったメソッドの対応
4. RecyclerView の自動リサイズ機能への対応
5. CircleCI の設定を更新

### 1. Support Library のバージョンを一括で管理する

これは Support Library のアップデートとは直接関係ありませんが、ずっと改善しなかったのを今回やっと修正したので、併せて取り上げてみました。

いろいろな Support Library を利用していると、アップデートするときそれぞれバージョンを修正するのは面倒ですよね。また基本的には各 Support Library はバージョンを揃えることが推奨されているため、変更を一箇所にまとめるのは理にかなってると言えます。

アプリの build.gradle を以下のように修正しました。注意点としては、compile 以降はダブルクォーテーションで括ることです。シングルクォーテーションではありません。

```groovy
ext {
  supportLibVersion = '23.3.0'
}

dependencies {
  compile "com.android.support:appcompat-v7:${supportLibVersion}"
  compile "com.android.support:design:${supportLibVersion}"
  compile "com.android.support:cardview-v7:${supportLibVersion}"
  ...
```

このあたりのことは、DroidKaigi 2016 Day2 の基調講演で Google の荒木さんが解説してくださっています。

- [Support Library ノススメ & Internal（動画）](https://www.youtube.com/watch?v=PJSB4xCc3Dg&t=10m39s)
- [Support Library ノススメ & Internal（スライド）](http://yaraki.github.io/slides/droidkaigi2016/#1)

### 2. runner や espresso が依存する support-annotations を除外する

プロジェクトで support-annotations を使っていたので同様にアップデートしたのですが、gradle-sync を実行したら espresso や runner が依存している support-annotations とコンフリクトしてしまいました。

そのため、build.gradle を以下のように修正しました。

```groovy
  androidTestCompile ('com.android.support.test:runner:0.4') {
    exclude module: 'support-annotations'
  }
  androidTestCompile ('com.android.support.test:rules:0.4') {
    exclude module: 'support-annotations'
  }
  androidTestCompile ('com.android.support.test.espresso:espresso-core:2.2.1') {
    exclude module: 'support-annotations'
  }
```

※ 後ほど確認したら espresso:2.2.2 や runner:0.5 が最新でしたが、やはりコンフリクトは起きたので当面除外するしかなさそうです。

### 3. TabLayout で新たに deprecated になったメソッドに対応する

design ライブラリに含まれている TabLayout クラスですが、（いつからか調べていませんが）ver23.3.0 では `setTabsFromPagerAdapter(PagerAdapter)` メソッドが deprecated になっていました。

**TabLayout.java**

```java
    /**
     * @deprecated Use {@link #setupWithViewPager(ViewPager)} to link a TabLayout with a ViewPager
     *             together. When that method is used, the TabLayout will be automatically updated
     *             when the {@link PagerAdapter} is changed.
     */
    @Deprecated
    public void setTabsFromPagerAdapter(@Nullable final PagerAdapter adapter) {
        setPagerAdapter(adapter, false);
    }
```

弊社アプリでは、このメソッドを Override したカスタム TabLayout を使用していたのですが、そこで行っていた処理は全て上書きされてしまうようになったので、TabLayout を利用する側で処理するように置き換えました。

上記コメントによると、どうやら PagerAdapter からタブを更新する処理を、TabLayout クラス内部で自動更新するようになったみたいですね。 TabLayout クラスを使ったカスタム View を使ってる場合は、一度確認して見たほうがいいかと思います。

※ この前は無かったのですが、 [リファレンス](http://developer.android.com/intl/ja/reference/android/support/design/widget/TabLayout.html#setTabsFromPagerAdapter(android.support.v4.view.PagerAdapter)) にも deprecated であることが明記されてました。

### 4. RecyclerView の自動リサイズ機能に対応する

これは以下の公式ブログでも紹介されてますが、RecyclerView にセットされる LayoutManager が、コンテンツサイズから自動で View をリサイズするように変更されています。
[Android Support Library 23.2 を公開 @ Google Developers Japan](http://googledevjp.blogspot.jp/2016/03/android-support-library-232.html)

実装の仕方にもよるかと思いますが、弊社アプリでは RecyclerView を使っている箇所の表示が崩れてしまうようになりました。

原因は上記の自動リサイズが効くようになったおかげで、RecyclerView で ViewHolder にセットしている View のレイアウトファイルで、 `android:layout_height="match_parent"` となっていたからです。

match_parent にしていると、リスト1つ1つが画面幅いっぱいの高さになってしまい、まるでページングするような RecyclerView になってしまいます。

修正方法は簡単で、 `android:layout_height="wrap_content"` に直すだけです。...だけなんですが、比較的対象が多いので、とても面倒な修正になりました。20箇所以上はこの修正をしたと思います。

なお手前味噌ですが、この内容について LT したことがあるので、もしよろしければ併せてご覧ください。
- [Support Library v23.2 overview @ shibuya.apk](https://speakerdeck.com/androhi/support-library-v23-dot-2-overview)

### 5. CircleCI の設定を更新する

弊社では CircleCI を利用しているのですが、Support Library を 23.3.0 にすると CircleCI の環境には無いというビルドエラーが発生してしまいました。

```
FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':app'.
> Could not resolve all dependencies for configuration ':app:_lollipopDebugCompile'.
   > Could not find com.android.support:appcompat-v7:23.3.0.
     Searched in the following locations:
         https://jcenter.bintray.com/com/android/support/appcompat-v7/23.3.0/appcompat-v7-23.3.0.pom
         ...
```

CircleCI の仮想環境には、以下の公式ドキュメントにあるように予め様々な Android SDK がプリインストールされていますが、Support Library 23.3.0 は含まれていないようです。

[Android on CircleCI](https://circleci.com/docs/android/)

これもドキュメントにある通り、無い場合は自分で設定ファイルに追記が必要です。今回は、Support Library のリポジトリ情報だけで良いので、ビルドを実行するタイミングの前に以下を追加しました。

```yaml
dependencies:
  pre:
    - echo y | android update sdk --no-ui --all --filter "extra-android-m2repository"
```

注意点として、ライセンスに同意するために `echo y` にパイプで繋げていますが、1つのライセンスに対してのみ効果があります。もし、異なるライセンスのものをインストールしたい場合には、ライセンス毎に分けて書く必要があります。

## まとめ

ver23.2.0 をまたいだアップデートは、機能追加以外にもいろいろな箇所に影響が出るので、一瞬アップデートを止めたくなりましたが、地道に修正していくと1つ1つは難しくない修正ばかりなので、もし二の足を踏んでいる方は上記を参考にアップデートに挑戦してみてはいかがでしょうか？

このアップデートを乗り越えれば、Vector Drawable サポートや BottomSheet サポート、DayNight モードなど、魅力的な新機能が使えるようになります。

## おまけ

Vector Drawable サポートについては、ver23.2.0/23.2.1 と ver23.3.0 間で少しややこしいことになっています。それについては、またまた手前味噌ですが別記事にまとめましたので、よろしければご覧ください。
[Support Vector Drawableのバージョン間差異について
](http://qiita.com/androhi/items/7398c7d7c5b07d14ab01)