Slide 1

Slide 1 text

謎現象の解決手段を発見して プチ英雄になりました Cybozu株式会社 市村 凌久

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

市村 凌久 ● サイボウズの25卒Androidアプリエンジニア ● kintone開発チーム ● 2025年は勉強会に20~30回くらい行ってたらしい 本LTはkintone Mobileの開発チームでのお話です 自己紹介

Slide 4

Slide 4 text

別チームからこんな連絡が来ました 「React版にしたらモバイルの機能動かなくなったんですけど」

Slide 5

Slide 5 text

🤔

Slide 6

Slide 6 text

kintoneの本体とモバイルの関係 kintone本体は ● 弊社、kintone本体のコードをReact版に刷新中 ● モバイルはWebViewベース、モバイルビューを用意 kintoneモバイルアプリは ● 部分的にネイティブ領域を実装することで、モバイル端末の体験を向上 ● webViewの addJavascriptInterface を用いてコールバックを公開し、 Web側から呼び出すことでネイティブ機能を展開

Slide 7

Slide 7 text

今までは通常通り動いていた 旧バージョン kintoneモバイルビュー kintone Android ②JSInterface ①操作 ③ネイティブ機能起動

Slide 8

Slide 8 text

刷新後の動作 React版 kintoneモバイルビュー kintone Android ②JSInterface ①操作 ③不発

Slide 9

Slide 9 text

刷新後の動作 React版 kintoneモバイルビュー kintone Android ②JSInterface ①操作 ③不発 ちなみにiOS版だと問題なく動作していた

Slide 10

Slide 10 text

刷新後の動作 React版 kintoneモバイルビュー kintone Android ②JSInterface ①操作 ③不発 ちなみにiOS版だと問題なく動作していた これってどっちが原因なんだ?

Slide 11

Slide 11 text

考えられる要因 本体 ● Reactではモバイル側のJSInterfaceをうまく参照できてない? ● React版で導入されたzod(バリデーションの仕組み)が悪さしている? ○ 依頼チームが削除してみたが結局疎通しなかった Android側 ● WebViewがReactやzodと相性が悪い? ● JSInterfaceの設計が悪い?

Slide 12

Slide 12 text

本LTの内容 AndroidのWebViewでReactサイト(?)を扱う時に 気をつけるべきこと

Slide 13

Slide 13 text

前提の共有 ● 僕自身Web技術に特別詳しいわけではないです ● もしかすると事実と異なる理解をしているかもですがご容赦を

Slide 14

Slide 14 text

モバイルチームを代表して原因究明を進める 🏃

Slide 15

Slide 15 text

まずは環境を再現 ● Reactでwebページをローカルに用意 ○ ほぼ初期テンプレートの実装 ○ ボタンを押したらJSInterfaceを呼び出す実装(zodは未使用) ○ ローカルホスティングで androidでもアクセスできるように設定 ● Androidも再現用のアプリを最低限の実装で用意 ○ WebViewを表示 ○ JSInterfaceでネイティブ画面に遷移する いざ、確認

Slide 16

Slide 16 text

ちゃんと動作する ● ReactとAndroidの相性が悪いわけではない

Slide 17

Slide 17 text

より実際の実装に寄せていく Web側 ● TypeScriptへ置き換え ● Zodを利用した呼び出しを使う Android側 ● JSInterfaceをクラス内でobject定義 ● Handlerでラップし、mainスレッド実行に いざ、確認

Slide 18

Slide 18 text

きた、呼び出せない! やはりzodが影響していた?

Slide 19

Slide 19 text

出力エラーから関連するissueを発見

Slide 20

Slide 20 text

原因 プロパティアクセスと呼び出しが分離する ことが問題 ● chromium(WebViewのベース)の仕様で、参照と実行が同時でないと JSInterfaceのメソッドをWeb側が実行できない ● zodはバリデーション時に一度参照するため、この条件に引っ掛かる ● zodを使わずとも、参照を返す実装ではJSInterfaceメソッドを実行できない

Slide 21

Slide 21 text

原因 プロパティアクセスと呼び出しが分離する ことが問題 と、ClaudeCodeさんが解説してくれました(重要) ● chromium(WebViewのベース)の仕様で、参照と実行が同時でないと JSInterfaceのメソッドをWeb側が実行できない ● zodはバリデーション時に一度参照するため、この条件に引っ掛かる ● zodを使わずとも、参照を返す実装ではJSInterfaceメソッドを実行できない

Slide 22

Slide 22 text

回避策 Web側でJSInterfaceの参照を渡す時、無名関数でラップする window // グローバルなブラウザアクセス .AndroidApp // JSInterfaceで決めた名前 .openNativeScreen() // JSInterfaceで定義したメソッド名 ❌ return window.AndroidApp.openNativeScreen ⭕ return () => { window.AndroidApp.openNativeScreen() } とにかく、JSInterfaceへのアクセスを実行する寸前まで触れてはいけないみたい

Slide 23

Slide 23 text

zodでやりたかったバリデーションはどうする? ● 今回対応したケースでは、手動で実装した ● 数行増える程度だが、毎回チェックを手動はめんどくさそう

Slide 24

Slide 24 text

結論 WebViewからJSInterfaceを公開する時 Webは参照と実行を分けてはいけない

Slide 25

Slide 25 text

感想 ● webとモバイルの知識の境界の問題解決って難しい ● モバイル以外の知識も要求され、幅広く知識をつけていく意識が芽生えた