如何在Xamarin HybridWebView中从React JSX调用C#代码
Xamarin HybridWebView 与 React 通信解决方案
根因说明
你遇到的invokeCSharpAction未定义报错,核心有两个原因:
- 直接调用注入方法时,默认会在当前模块作用域查找变量,不会自动匹配Xamarin注入到window全局的函数
- 代码执行时机早于Xamarin的JS注入动作,方法还没挂载到全局就被调用了
具体解决方案
1. 普通独立JS文件调用改造
所有调用注入方法的位置,都从window全局对象取值,同时增加重试逻辑兼容注入延迟:
function invokeCSCode(data) { if (window.invokeCSharpAction) { window.invokeCSharpAction(data); return; } // 注入未就绪时增加重试,最多重试5次,间隔100ms let retryCount = 0; const retryTimer = setInterval(() => { retryCount++; if (window.invokeCSharpAction) { window.invokeCSharpAction(data); clearInterval(retryTimer); } if (retryCount >= 5) { clearInterval(retryTimer); console.error('C#通信方法注入失败'); } }, 100); }
2. React JSX 内调用示例
函数组件内直接从window对象取注入方法即可,参考实现:
import { useState } from 'react'; const HybridTest = () => { const [inputValue, setInputValue] = useState(''); const [result, setResult] = useState('Result:'); const handleInvokeCsharp = () => { setResult(prev => `${prev} 发送参数:${inputValue}`); try { if (window.invokeCSharpAction) { window.invokeCSharpAction(inputValue); } else { setResult(prev => `${prev} 通信方法未就绪`); } } catch (err) { setResult(prev => `${prev} 调用错误:${err.message}`); } }; return ( <div> <h1>HybridWebView Test</h1> <div> 输入内容:<input type="text" value={inputValue} onChange={(e) => setInputValue(e.target.value)} /> </div> <button onClick={handleInvokeCsharp} style={{margin: '16px 0'}}> 调用C#代码 </button> <p>{result}</p> </div> ); }; export default HybridTest;
3. Xamarin 端注入逻辑优化
在WebViewClient的OnPageFinished回调中补充一次JS注入,确保页面加载完成后方法一定存在:
// 在你自定义的JavascriptWebViewClient类中重写OnPageFinished方法 public override void OnPageFinished(Android.Webkit.WebView view, string url) { base.OnPageFinished(view, url); // 页面加载完成后重新注入通信函数 view.EvaluateJavascript($"javascript: function invokeCSharpAction(data){{jsBridge.invokeAction(data);}}", null); }
4. React 打包部署注意事项
- 使用create-react-app打包时,在
package.json中配置homepage: ".",确保静态资源使用相对路径,避免放入Android assets目录后加载失败 - 不需要关闭React严格模式,也不需要修改打包混淆规则,只要所有调用都从window对象取方法即可
内容的提问来源于stack exchange,提问作者Sunday
相关产品推荐
相关产品推荐

