React NativeのSVGを使うライブラリをAndroidで動かすときにエラー
はじめに
最近、React Nativeの開発を積極的にしています。 その折り、ちょっとしたグラフを書きたくなったのでreact-native-chart-kitというライブラリを使っていました。
iOSでは問題なく動いていたのに、いざAndroidで動かそうとすると動かなかった(しかも実機のみ!)ので、 備忘録として対処を残しておきます。
利用準備
READMEに記載の通り、npmかyarnでライブラリをインストールすることで使うことができます。 なお、react-native-svgが入っていないと動かないので、こちらのライブラリも必要でした。
$ yarn add react-native-svg // 必要であれば $ yarn add react-native-chart-kit
あとはExampleに記載の通り実装することでバーチャートやパイチャートなどを描画できます。
発生した事象
iOS
こちらではシミュレータ、実機いずれも問題なく動きます。
Android
こちらで死にました。。。React Nativeではどちらもテストが必要なのが辛いですね。。。 また、Androidでも下記の通り、挙動が変わります。
動作状況 | 結果 |
---|---|
Android Emulator | OK |
USBからAPKを転送 | OK |
APKをインストール | NG |
単純に実機だとうごかないのではなく、USBデバッグの段階では動くというのが今回いやらしかったです;; NGというのは「[アプリ名]が停止しました」というアラートが出てアプリが落ちた状態を指しています。
原因
adb logcatをしてログを確認すると下記の通り、Exceptionが吐かれていました。 ライブラリ内のNoSuchFieldExceptionとか知らんよーーってなりましたw
07-23 23:00:50.149 10915 10915 E AndroidRuntime: FATAL EXCEPTION: main 07-23 23:00:50.149 10915 10915 E AndroidRuntime: Process: xxxx.xxxx.xxxx, PID: xxxxxx 07-23 23:00:50.149 10915 10915 E AndroidRuntime: java.lang.IllegalStateException: java.lang.NoSuchFieldException: fill 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.v.a() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.j.c() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.X.a() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.v.b() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.j.c() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.j.a() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.v.b() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.j.c() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.j.a() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.v.b() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.j.c() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.j.a() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.v.b() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.C.a() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.C.j() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.horcrux.svg.C.onDraw() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:17122) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16104) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:16888) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.drawChild(ViewGroup.java:3764) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.facebook.react.views.view.h.dispatchDraw() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:17125) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16104) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:16888) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.drawChild(ViewGroup.java:3764) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.facebook.react.views.view.h.dispatchDraw() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:17125) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16104) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:16888) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.drawChild(ViewGroup.java:3764) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.facebook.react.views.view.h.dispatchDraw() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16099) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:16888) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.drawChild(ViewGroup.java:3764) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.facebook.react.views.view.h.dispatchDraw() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:17125) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16104) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:16888) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.drawChild(ViewGroup.java:3764) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.facebook.react.views.view.h.dispatchDraw() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16099) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:16888) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.drawChild(ViewGroup.java:3764) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.facebook.react.views.view.h.dispatchDraw() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16099) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:16888) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.drawChild(ViewGroup.java:3764) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.facebook.react.views.view.h.dispatchDraw() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16099) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.draw(View.java:16888) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.drawChild(ViewGroup.java:3764) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchDraw(ViewGroup.java:3550) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at com.facebook.react.views.view.h.dispatchDraw() 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16099) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16067) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16067) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16067) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16067) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748) 07-23 23:00:50.149 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16067) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16067) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:3748) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3728) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.View.updateDisplayListIfDirty(View.java:16067) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:656) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:662) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:770) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ViewRootImpl.draw(ViewRootImpl.java:2800) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2608) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2215) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1250) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6311) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:871) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.Choreographer.doCallbacks(Choreographer.java:683) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:619) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:857) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:751) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.os.Looper.loop(Looper.java:241) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6217) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: Caused by: java.lang.NoSuchFieldException: fill 07-23 23:00:50.150 10915 10915 E AndroidRuntime: at java.lang.Class.getField(Class.java:1549) 07-23 23:00:50.150 10915 10915 E AndroidRuntime: ... 101 more 07-23 23:00:50.166 756 850 E JavaDumper:FW: utils.c(248): mkdir (/data/crashdata) failed. File exists
修正内容
困ったときはコミュニティやGoogle様に聞くことが肝心で同じように困った人がやはりいました。下記によるとProguardファイル(proguard.pro)に下記を書くとよいようです。ようするにExceptionの原因となっている、「com.horcrux.svg」パッケージへのリフレクション時の参照時にNo such Fieldといわれているので、参照名と参照プログラムを残すような処理になります。
-keep public class com.horcrux.svg.** {*;}
まとめ
相変わらず、React Nativeを書くときはネイティブを触るときのデバッグや各ネイティブ向けの設定が必要だなと痛感しました。