こんにちは。
近い内ついに八戸にタピオカ専門店ができるらしい、mukaiyachiです。
いつもはMacで開発を行っているのですが、同じプロジェクトをWindowsを使用している方がビルドしたところ、例外が発生するといったことがありました。
例えば以下のようなレイアウトがあり、この中のID「mailSettingText」にはDataBindingで受け取った値によって表示する文字列を切り替えるとします。
「mainViewModel.mailSetting.received」がtrueであれば「受信する」、falseであれば「受信しない」となります。
「受信する」「受信しない」はXMLに直接書いていて、ダブルクォーテーションのエスケープのために「"」を使っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainFragment" android:id="@+id/layout"> <data> <variable name="mainViewModel" type="info.mukaiyachi.databindingwindows.MainViewModel"/> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/title" android:text="メール配信設定" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/mailSettingText"/> <TextView android:id="@+id/mailSettingText" android:text="@{mainViewModel.mailSetting.received ? "受信する" : "受信しない"}" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/title"/> </androidx.constraintlayout.widget.ConstraintLayout> </layout> |
これはMac環境でビルドする際はうまくいきますが、Windows環境では「MalformedByteSequenceException」が発生しビルドできません。
Windows環境ではDataBindingを使用してViewに値を設定する際に、XMLに直接文字列を書くと例外が発生するものがあるようです。
上記の例ではダブルクォーテーション「”」のエスケープ文字「"」が例外の原因となる文字でした。
それ以外にも私の調べた限りでは以下の文字が例外の原因となる文字でした。
(漢字は調査していないので、漢字を入れるともっと多くなると思います。)
◎ひらがな
う
え
む
ゆ
よ
だ
ぅ
ゅ
◎カタカナ
テ
ト
フヘ(2つの文字が連続していない場合は問題なし)
ム
ダ
ヅ
ベボ(2つの文字が連続していない場合は問題なし)
ペポ(2つの文字が連続していない場合は問題なし)
◎全角数字
1234567890いずれも
◎全角アルファベット大文字
A〜Zの文字全て
◎全角アルファベット小文字
a〜zの文字全て
◎記号
〜
−
なので以下の場合も「よ」「だ」が入っているため例外が発生します。
1 |
android:text="@{mainViewModel.mailSetting.received ? `よい` : `だめ`}" |
ちなみに調査時点のAndroid Studioのバージョンは「3.4.1」です。
対応としては文字列を直接レイアウトのXMLに書くのではなく、string.xml等の文字列リソースに一度定義しそれを呼び出すようにします。
1 2 3 4 |
<resources> <string name="receive">受信する</string> <string name="not_receive">受信しない</string> </resources> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainFragment" android:id="@+id/layout"> <data> <variable name="mainViewModel" type="info.mukaiyachi.databindingwindows.MainViewModel"/> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/title" android:text="メール配信設定" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toTopOf="@id/mailSettingText"/> <TextView android:id="@+id/mailSettingText" android:text="@{mainViewModel.mailSetting.received ? @string/receive : @string/not_receive}" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@id/title"/> </androidx.constraintlayout.widget.ConstraintLayout> </layout> |
android:text="@{mainViewModel.mailSetting.received ? "受信する" : "受信しない"}"
↓
android:text="@{mainViewModel.mailSetting.received ? @string/receive : @string/not_receive}"
日頃からレイアウトXMLにはなるべく文字列を直接書かないように気をつけていきましょう!