Unity用のAppsFlyerというSDKを組み込み、Androidで動かしてみたら
「Exception: No such proxy method: UnityEngine.AndroidJavaRunnableProxy.run()」
というエラーがlogcat上に出てアプリが動作しない問題が発生した。
原因は、Unityの機能であるStripping(ストリッピング)が悪さをしていました。
その悪さをどのように解決したのか解説します。
発生したこと
開発環境
・Unity2017.4.19
・書き出しプラットフォームはAndroid
Unity用のAppsFlyerという広告用SDKを入れたら、以下のようなエラーが出てインストールリファラーを正しく取れないという問題が発生しました。
実際に出力されたエラー
03-05 18:07:10.946 20565 20565 E Unity : Exception: No such proxy method: UnityEngine.AndroidJavaRunnableProxy.run()
03-05 18:07:10.946 20565 20565 E Unity : at UnityEngine.AndroidJavaProxy.Invoke (System.String methodName, System.Object[] args) [0x00000] in :0
03-05 18:07:10.946 20565 20565 E Unity : at UnityEngine.AndroidJavaProxy.Invoke (System.String methodName, UnityEngine.AndroidJavaObject[] javaArgs) [0x00000] in :0
03-05 18:07:10.946 20565 20565 E Unity : at UnityEngine._AndroidJNIHelper.InvokeJavaProxyMethod (UnityEngine.AndroidJavaProxy proxy, IntPtr jmethodName, IntPtr jargs) [0x00000] in :0
原因はUnityのストリッピング機能だった
AppsFlyerの担当者に上記のエラー内容を見せたら、ストリッピングの問題であることを教えて頂きました。
ストリッピングとは、不要な部分を削除するという意味で、Unityにおいてはビルド時、不必要なコードをなくして、アプリ容量を減らす役割があります。
私の環境も、アプリ容量を減らしたかったので
「Stripping Level」 の設定を「Strip Byte Code」にしていました。
その結果、ストリッピングする際に、本来必要な処理まで消されてしまったようです。
対処方法
今回の問題は、「Stripping Level」を調整することにより解決しました。
Stripping Levelは、以下のところで変更可能です。
メニューより
File->Build Settings->Player Settings->Other Settings->Stripping Level
StrippingLevelについて
https://docs.unity3d.com/ScriptReference/StrippingLevel.html
具体的な対処方法は、以下の通りです。
対処方法1・Stripping Level の設定をDisabledにする
Stripping Level の設定をDisabledにする。つまり、
つまり、ストリッピングを使わないようにします。
■メリット
AndroidJavaRunnableProxyエラーのようなストリッピングによる不具合に遭遇しない。
開発速度をあげたいときに良い。
■デメリット
コードの最適化が行われないため、アプリ容量が大きくなる。
特に、広告計測ツールなどのSDKを入れるとアプリ容量が増えるので注意が必要です。
対処方法2・ストリッピングさせないメソッドを指定する
link.xmlを使い、メソッドに対しストリッピングの対象から外しします。
link.xmlファイルは、Assets以下ならばどこにおいても良いです。
今回のように、AndroidJavaRunnableProxyメソッドをストリッピングの対象から外す場合は、
link.xmlファイルに以下のように記述します。
以下の意味は、AndroidJavaRunnableProxyメソッドを(削らないで)元の状態を保つです。
<linker>
<assembly fullname="UnityEngine">
<type fullname="UnityEngine.AndroidJavaRunnableProxy" preserve="all"/>
</assembly>
</linker>
linkの設定については、詳しくは以下を参照
IL2CPP を使ったマネージバイトコードストリップ
https://docs.unity3d.com/ja/current/Manual/IL2CPP-BytecodeStripping.html
■メリット
アプリの容量を減らすことができる。
■デメリット
メソッドごとに設定する必要がある。
ストリッピングに失敗するかどうかは、Android端末で動かして見ないとわかりません。
もし不具合が起きたとき、ログを追う必要があるので、調査などの手間がかかる。
まとめ
AndroidJavaRunnableProxyのように、こんなはずじゃないと思ったらストリッピングを疑っても良いかもしれませんね。
実装にはまったら、一人で悩まずその道に詳しい人に相談してみよう・タイムチケット