androidアプリのサブプロジェクトのlintチェックで依存関係エラー

こんにちは。

この間、サブプロジェクトを含むandroidアプリをビルドしていたときに出たエラーについてお話しします。

#バージョン

* `gradle 4.6`
* `android gradle plugin 3.2.1`

#出たエラー

エラーはこんな感じです。

```
> Task :subproject:lint 
Ran lint on variant debug: 5 issues found
Ran lint on variant release: 5 issues found
Wrote HTML report to file:///path/to/subproject/build/reports/lint-results.html
Wrote XML report to file:///path/to/subproject/build/reports/lint-results.xml


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':subproject:lint'.
> Lint found errors in the project; aborting build.
  
  Fix the issues identified by lint, or add the following to your build script to proceed with errors:
  ...
  android {
      lintOptions {
          abortOnError false
      }
  }
  ...
  
  Errors found:
  
  /path/to/subproject/build.gradle: Error: All com.android.support libraries must use the exact same version specification (mixing versions can lead to runtime crashes). Found versions 28.0.0, 26.1.0. Examples include com.android.support:collections:28.0.0 and com.android.support:animated-vector-drawable:26.1.0 [GradleCompatible]
```

androidのsupportライブラリのバージョン競合エラーっぽいです。

#試行錯誤

supportライブラリの依存関係エラーについてはいろいろなサイトで解決方法が紹介されています。

とりあえず、

```bash
$ ./gradlew app:dependencies | grep 'com.android.support'
```

を実行して依存関係を調べてみたのですが、、、

supportライブラリは全部`28.0.0`になっていて特に問題があるようには見えません。

そこで試しに、

```bash
$ ./gradlew subproject:dependencies | grep 'com.android.support'
```

を見てみると、、、

```
|    +--- com.android.support:appcompat-v7:26.1.0
|    |    +--- com.android.support:support-annotations:26.1.0 -> 28.0.0
|    |    +--- com.android.support:support-v4:26.1.0
|    |    |    +--- com.android.support:support-compat:26.1.0 -> 28.0.0
|    |    |    |    +--- com.android.support:support-annotations:28.0.0
|    |    |    |    +--- com.android.support:collections:28.0.0
|    |    |    |    |    \--- com.android.support:support-annotations:28.0.0
|    |    |    |    |    |    \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
|    |    |    |    |    |    \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
|    |    |    |    |    \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
|    |    |    |    \--- com.android.support:versionedparcelable:28.0.0
|    |    |    |         +--- com.android.support:support-annotations:28.0.0
|    |    |    |         \--- com.android.support:collections:28.0.0 (*)
|    |    |    +--- com.android.support:support-media-compat:26.1.0
|    |    |    |    +--- com.android.support:support-annotations:26.1.0 -> 28.0.0
|    |    |    |    \--- com.android.support:support-compat:26.1.0 -> 28.0.0 (*)
|    |    |    +--- com.android.support:support-core-utils:26.1.0 -> 28.0.0
|    |    |    |    +--- com.android.support:support-annotations:28.0.0
|    |    |    |    +--- com.android.support:support-compat:28.0.0 (*)
|    |    |    |    +--- com.android.support:documentfile:28.0.0
|    |    |    |    |    \--- com.android.support:support-annotations:28.0.0
|    |    |    |    +--- com.android.support:loader:28.0.0
|    |    |    |    |    +--- com.android.support:support-annotations:28.0.0
|    |    |    |    |    +--- com.android.support:support-compat:28.0.0 (*)
|    |    |    |    |    |    |    +--- com.android.support:support-annotations:26.1.0 -> 28.0.0
|    |    |    |    |         \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
|    |    |    |    +--- com.android.support:localbroadcastmanager:28.0.0
|    |    |    |    |    \--- com.android.support:support-annotations:28.0.0
|    |    |    |    \--- com.android.support:print:28.0.0
|    |    |    |         \--- com.android.support:support-annotations:28.0.0
|    |    |    +--- com.android.support:support-core-ui:26.1.0
|    |    |    |    +--- com.android.support:support-annotations:26.1.0 -> 28.0.0
|    |    |    |    \--- com.android.support:support-compat:26.1.0 -> 28.0.0 (*)
|    |    |    \--- com.android.support:support-fragment:26.1.0
|    |    |         +--- com.android.support:support-compat:26.1.0 -> 28.0.0 (*)
|    |    |         +--- com.android.support:support-core-ui:26.1.0 (*)
|    |    |         \--- com.android.support:support-core-utils:26.1.0 -> 28.0.0 (*)
|    |    +--- com.android.support:support-vector-drawable:26.1.0
|    |    |    +--- com.android.support:support-annotations:26.1.0 -> 28.0.0
|    |    |    \--- com.android.support:support-compat:26.1.0 -> 28.0.0 (*)
|    |    \--- com.android.support:animated-vector-drawable:26.1.0
|    |         +--- com.android.support:support-vector-drawable:26.1.0 (*)
|    |         \--- com.android.support:support-core-ui:26.1.0 (*)
|    |    |    \--- com.android.support:support-v4:26.1.0 (*)
\--- com.android.support:support-core-utils:28.0.0 (*)
```

`26.1.0`と`28.0.0`が競合していました。

どうやら、サブプロジェクト単体で依存関係エラーが起こっていたみたいです。

他のプロジェクトと合わせてビルドすることで依存バージョンが`28.0.0`に上がり、`app:dependencies`では競合がなくなっていたのだと思います。

#解決策

本当ならばここでサブプロジェクトAの`build.gradle`を編集してすべて`28.0.0`にそろえたいところです。

しかし今回の私のケースではサブプロジェクトはgitに追跡されないところから読み込んでいるので、直接いじりたくありません。

そこで、メインプロジェクトのルートの`build.gradle`からサブプロジェクトの設定を上書きすることにしました。

```gradle
project(':subproject') {
    afterEvaluate {project ->
        if (project.hasProperty("android")) {
            android {
                lintOptions {
                    abortOnError false
                }
            }
        }
    }
}
```

ここで注意するのは、今対処しているのはビルドエラーというよりlintチェックのエラーだということです。

今回得られたlintエラーは無視しても問題ないものなので、これを無視するよう設定を上書きします（なぜならlintチェックしている依存関係と実際にビルド時に使われる依存関係が違っているから）

#最後に

この方法でいいのかイマイチはっきりしてません。

できればlintチェックを残したままサブプロジェクトの依存関係チェックだけスルーできるようにしたかったのですが、これしか思いつきませんでした。

もっと冴えた方法があればぜひ教えてください

#参考

* https://android.benigumo.com/20180309/support-library-versions-conflict/
* https://maku77.github.io/android/gradle/ignore-lint-errors.html