いやなダイアログだ。思わずため息が出る。Unity Android開発者は何度このダイアログに悩まされることになるのだろう。
環境
Unity Editor: Unity 2021.1.6f1
Platform: Android
OS: macOS Monterey(12.6)
Target API Level: Android 11 (API Level 30)(当初)
前回のあらすじ
リリースだけ起こるバグに遭遇したが、ProGuardの難読化が原因だったことがわかった。
proguard-user.txtに追記して、難読化を回避することでなんとかProGuardの罠を潜り抜け、ようやくリリースビルドが完成した。
Googleさん「APIレベル上げろや」
そして早速Google Play Consoleでアップロードしてみると、、
「現在、お客様のアプリは API レベル 30 を対象にしています。セキュリティとパフォーマンスが最適化された最新の API を利用するには、API レベル 31 以上を対象にする必要があります。アプリの対象 API レベルを 31 以上に変更してください。」
とのこと。いやいやいや… ちょっと前OKでしたやん。なんで今になって言うん…
仕方ないので、APIレベルを31に上げることにした。
それがGradle地獄の始まりだった。
Gradleエラー、Gradleエラー、Gradleエラー
API Levelを上げることはそんなに難しくない。
Build Settings→Player→Other Settings→Identification→Target API Level
これを変更するだけ。あとはUnityがAPI Level 31のSDKをインストールしてくれる。
まあまあ落ち着けって。こう言う時はだいたいPlugins/Androidのaarファイルを一旦全部消して、Force Resolveをすればだいたい解消するんだって(詳しくは→ AppLovin Max SDK for Unity をAndroidでビルドエラーの解決 )
しかし、無情の Build failure
んんん?待て待て、たんにAPIレベル上げただけだぞ?そんなたいそうなことか?
仕方ない、ちゃんとConsole見てみるかと、やってみると…
はいはい、ですよねー。なんかこういうふうに該当のところをクリックすると、UnityEditorがバグって全部消えるんですよ。Gradleエラーあるあるなんですよー。
じゃあ、Editor.logを直接見るしかない。
Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8
コンパイラで例外が発生しました(1.8.0-adoptopenjdk)。Bug Database (http://bugs.java.com)で重複がないか
をご確認のうえ、Java bugレポート・ページ(http://bugreport.java.com)でJavaコンパイラに対するbugの登録を
お願いいたします。レポートには、そのプログラムと下記の診断内容を含めてください。ご協力ありがとうございます。
java.lang.AssertionError: annotationType(): unrecognized Attribute name MODULE (class com.sun.tools.javac.util.UnsharedNameTable$NameImpl)
at com.sun.tools.javac.util.Assert.error(Assert.java:133)
at com.sun.tools.javac.code.TypeAnnotations.annotationType(TypeAnnotations.java:231)
at com.sun.tools.javac.code.TypeAnnotations$TypeAnnotationPositions.separateAnnotationsKinds(TypeAnnotations.java:294)
at com.sun.tools.javac.code.TypeAnnotations$TypeAnnotationPositions.visitVarDef(TypeAnnotations.java:1164)
ご協力ありがとうございますじゃねえよ。とか言いたくなる。
とにかくエラーが要領を得ない。「unrecognized Attribute name MODULE」ってどういうこと?
ワタシはAPIレベルをアゲたダケダガ?
Googleで検索
とにかくエラーを見ていてもわからなそうなので、Googleで調べてみることにした。こういうとき、エラーメッセージを検索するに限る。
検索ワードを
java.lang.AssertionError: annotationType(): unrecognized Attribute name MODULE (class com.sun.tools.javac.util.UnsharedNameTable$NameImpl)
として検索してみると、
というそれらしい感じの質問にあたった。
アンサーが色々あって、
JDKを8でやる必要がある
いや11でよい
Android Gradle Plugin のバージョンをあげろ
Android Build Toolsはバージョン30.0.*だけにしろ
しまいにはAPIレベルを30にダウングレードしろとかいうのもあった。(さすがにこれは叩かれていたが)
どうやら各人の環境によって解決が異なるということがわかった。なので私もいろんな方法でやってみた。
以下は私の方でうまくいった方法だが、他の人もうまくいくかどうかはわからない。これ以外にも方法があるかもしれない。
対応策1、Gradleのバージョンを変更
Gradleにはバージョンがあって、それがどうやら古いとAPIレベル31はビルドできないっぽいらしい。
私の使っているUnityは2021.1.6f1なので、Gradleバージョンは「5.6.4」だ。それを「6.1.1」にしないといけない。
私はたまたまUnityのもう少し上のバージョン2021.3.4f1をインストールしてあったので、そちらのGradleバージョンは幸い「6.1.1」でこれを使うことにした。
メニューのPreferenceから、External Toolsを選んで、「Gradle Installed with Unity」のチェックを外し、Gradleの場所を変更する(私はUnity2021.3.4f1のものを使うことにした)。
これでうまくいくだろ。
対応策2、Android Build Toolsはバージョン30.0.*だけにする
ここにある通り、実は状況はかなり複雑だ。
要はAndroid側とUnity側のビルドツールのバージョンの不整合が原因、ということだ。
なので、Android SDKはAPIレベルを31にしつつ、ビルドツールバージョンを下げて30.0.Xにする必要がある。これするにはUnity内部のAndroid SDKではカスタマイズが難しい。
なので、これは自分でAndroid SDKをダウンロードする必要がある。
Android SDKはAndroid StudioのSDK Managerでインストールする
SDK Platforms で Android API 31が必要なのと、
SDK Tools のタブで「Show Package Details」で細かいバージョン指定ができるようにして、31以上は全てアンインストールして、30.0.X(図では30.0.3)を一つだけインストールする
そしてUnityでPreferenceの
先程のExternal Toolsで、「Android SDK Tools Installed with Unity」のチェックを外し、自分でダウンロードしてきたAndroid SDKの場所を入れる。
今度こそうまくいくだろ(フラグ)
対応策3、Custom Base Gradle Template を使う
先程のGoogleの資料によると、
Gradleのバージョンは6.1.1にバージョンアップするのだが、同時にAndroid Gradle Pluginは4.0.1にする必要がある、らしい。(何?もっかい言って?)
Gradleバージョンとは別に、Gradle Pluginのバージョンというのがあって、そちらを4.0.1にする必要があることらしい。(知らんがな!)
もーここまで来るとトンチキ過ぎて頭に来るが、最後まで付き合うしかない。
というわけで、上の資料にある通り、「Custom Base Gradle Template」を使って、
Assets/Plugins/Android/baseProjectTemplate.gradle
を編集する。その中の
classpath 'com.android.tools.build:gradle:3.6.0'
というところを
classpath 'com.android.tools.build:gradle:4.0.1'
に変更する。
あと、最初の行
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
も消しておく。
対応策4、AndroidManifest.xmlの編集
もう一つやることがある。
先程のGoogle の資料によると、AndroidManifest.xmlの一部を修正する必要があるらしい。
<application>
<activity android:name="com.unity3d.player.UnityPlayerActivity"
android:theme="@style/UnityThemeSelector"
android:exported="true">
:
(略)
最後の「android:exported="true"」というところを追記する必要があった。
今度こそ、今度こそうまくいくだろ(懇願)
Gradle地獄の歩き方
というわけでGradle地獄は終わったのだが、ひとつGradleエラーの読み方があることに気がついた。
大量のEditor.logの中で、
* What went wrong:
という文言で始まるログがあり、それが問題の根幹であるようだ。
なので検索する文字列としては、そのログを使うのが良さそうだ。
以上!