環境
Unity Editor: Unity 2021.1.6f1
Platform: Android
OS: macOS Monterey(12.6)
Target API Level: Android 11 (API Level 30)(当初)
リリースビルドだけ起こるバグ
UnityのAndroid版ゲームのビルドを作っているとき、Debugでは問題ないのだが、Releaseでビルドしたら進行不能バグに遭遇した。
logcatで内容を見てみると、いろんなことで以下の例外が出ている。
E/Unity: AndroidJavaException: java.lang.ClassNotFoundException:
「ClassNotFoundException」つまり、そのクラスが見つからないということ。しかし該当のファイルは存在するし、そもそもDebugでは問題なく動いている。
問題の洗い出し
どういうことかと調べたら、どうやら「ProGuard」という難読化ツールが名前を変更したから、らしい。
しかしそもそも「ProGuard」なんてツールを使用した覚えはないなのだが、、、
よく調べていくと、どうやら「Minify」というツールがAndroidのReleaseビルドで発動するようにデフォルトでなっているようで。
ProjectSettings→Player→Publish Settings→Minify
それのおかげ(それのせい?)で「ProGuard」が発動し、例外を吐いていたということのようだ。
つまりまとめると、
Release ビルドにする
↓
MinifyはReleaseビルドではデフォルトオンになっているのでMinify発動
↓
MinifyのなかでProGuardがコードの難読化が発動
↓
自分のソースコードは難読化が成功するのだが、外部プラグインの難読化が整合性が取れなくなる
↓
プラグインの「ClassNotFoundException:」例外が出る
という仕組みだったようだ。
難読化してほしくないプラグインの設定
Assets/Plugins/Android/proguard-user.txt
というテキストファイルを作って、これにProGuardで難読化してほしくない部分を追記していく。
どう書けばいいかわからないと思うが、だいたいそのプラグインの「ProGuard項目」にどう書けばいいか書いてある。
例えば、「applovin SDK proguard」とかで検索すると、それらしい項目があるので、
-keepattributes Signature,InnerClasses,Exceptions,Annotation
-keep public class com.applovin.sdk.AppLovinSdk{ *; }
-keep public class com.applovin.sdk.AppLovin* { public protected *; }
-keep public class com.applovin.nativeAds.AppLovin* { public protected *; }
-keep public class com.applovin.adview.* { public protected *; }
-keep public class com.applovin.mediation.* { public protected *; }
-keep public class com.applovin.mediation.ads.* { public protected *; }
-keep public class com.applovin.impl.*.AppLovin { public protected *; }
-keep public class com.applovin.impl.**.*Impl { public protected *; }
-keepclassmembers class com.applovin.sdk.AppLovinSdkSettings { private java.util.Map localSettings; }
-keep class com.applovin.mediation.adapters.** { *; }
-keep class com.applovin.mediation.adapter.**{ *; }
引用:https://developers.is.com/ironsource-mobile/unity/applovin-mediation-guide/#step-3
それを丸ごとコピーして、proguard-user.txtに追記していく。
その作業を全ての外部プラグインに関して行うということになる。もし忘れてしまうと、実行時にひっそり例外が出るだけでビルドできてしまうので、細心の注意が必要となる。
Androidビルドの険しい道は続く
ちなみにこの後もまだ「Gradle地獄」が続くのだが、その話は次回→「UnityのAndroidビルドでAPIレベル31にしたらGradle地獄だった話」