Help us understand the problem. What is going on with this article?

Android 4.4以下でReact NativeのSwitchが動かない場合の対処

More than 1 year has passed since last update.

React nativeのAndroid特有のトラブルシューティングについてのお話です。Android 4.4でこういうのが出ました。

device-2018-02-13-040940.png

This app has been build with an incorrect configuration. Please configure your build for VectorDrawableCompat.

スタックトレースから原因を推測してみる

JSのスタックトレース的には

  • ReactSwitchManager.java
  • SwitchCompat.java

あたりを通っているので、どうやら <Switch> コンポーネントがやらかしているらしいことまでは分かります。今回のケースでもSwitchを使っていましたし、Switchをコメントアウトしたらエラーが出なくなりました。

JSのスタックトレース的には

JSじゃないですねそうですね

Android開発の経験則から原因を推測してみる

実はスタックトレースを追わなくても、Android開発に慣れ親しんだエンジニアであれば次の2つのキーワードで察しが付いたりします。

  • Android 4.4(5.0未満)
  • VectorDrawableCompat

VectorDrawableはAndroidでSVGライクなベクターイメージを扱うための機能なのですが、導入されたのはAndroid 5.0からです。それ以下のバージョン向けにはSupport Library(JSでいうPolyfill)が用意されていますが、これもオプトイン方式なので、デフォルトでは有効になっていません。

このSupport Library版VectorDrawableがVectorDrawableCompatです。これを有効にすることで、エラーが解消されます。

そんなわけで、この問題は完全にJava側の方法論でしか解決できないやつでした。Android StudioでLogCatを見てみると、もう少し詳しいスタックトレースが見れます。

スクリーンショット 2018-02-13 4.17.07.png

直し方

それでは直し方です。できたらAndroid Studioをご用意ください。無ければVS Codeとかでもいいです。

1. build.gradleに設定を追記

app内のbuild.gradleに vectorDrawables.useSupportLibrary = true を書いてください。VectorDrawableCompatが使えるようになります。

android/app/build.gradle
android {
    // 省略
    defaultConfig {
        // 省略
        vectorDrawables.useSupportLibrary = true
    }

2. 魔法のフラグをオンにする

VectorDrawableCompatを使う場合、本来であれば適切に app:srcCompat
ImageView#setImageResource を利用するなどの措置
が必要になりますが、今回のように公式提供のNative Componentsが相手ではそうもいきません。

そんなときのために、少しパフォーマンスを犠牲にするものの、VectorDrawableCompatに関する問題を雑に解決するためのフラグがあります。

android/app/src/main/java/com.yourapp.MainActivity
public class MainActivity extends ReactActivity {

    static {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }

上記のように、staticブロックで AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); を実行しておくと、このstaticが生存している間は全ての画像読み込みが「VectorDrawableの可能性あり」と判断されて、様々な判定の対象となります(なのでパフォーマンスが犠牲になるのです)。

3. 解決

私の手元ではこれで無事にSwitchが表示されるようになりました。

もうちょっと正統派の解決策も見つけられそうな気がしなくもないですが、ひとまずこれが手っ取り早いと思います。

最後に

こういうJSer殺しな罠があるのはどうかと思う・・・・

追記:2018.3.29

再発した・・・機種依存の可能性ありますね・・・・

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした