You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin Forms中JS调用C#遇阻:HybridWebView示例Android版本失效求助

Android端HybridWebView JS回调失效的修复方案

针对你遇到的Xamarin.Forms官方HybridWebView示例Android端无法工作的问题,结合支付iframe的场景,给你几个针对性的修复点:

1. 强制开启WebView的JS与DOM存储支持

Android WebView默认可能未启用JavaScript或DOM存储,这是支付iframe运行的基础,在渲染器里添加:

Control.Settings.JavaScriptEnabled = true;
Control.Settings.DomStorageEnabled = true;
// 若支付页面需要缓存,可开启:
Control.Settings.CacheMode = CacheModes.LoadDefault;

2. 规范JavaScriptInterface的注解与实现

Android 17及以上版本要求JS交互方法必须添加[JavascriptInterface]注解,且类和方法必须是public:

public class HybridWebInterface : Java.Lang.Object
{
    readonly WeakReference<HybridWebViewRenderer> _rendererRef;

    public HybridWebInterface(HybridWebViewRenderer renderer)
    {
        _rendererRef = new WeakReference<HybridWebViewRenderer>(renderer);
    }

    [JavascriptInterface] // 必须加这个注解
    public void OnPaymentCallback(string callbackData)
    {
        if (_rendererRef.TryGetTarget(out var renderer))
        {
            // 触发Xamarin.Forms端的命令或事件
            ((HybridWebView)renderer.Element).OnPaymentCompleted(callbackData);
        }
    }
}

注册接口时要指定JS调用的名称,确保和iframe里的JS代码对应:

Control.AddJavascriptInterface(new HybridWebInterface(this), "AppPaymentBridge");

iframe里的JS要这样调用:window.AppPaymentBridge.OnPaymentCallback('支付成功/失败的JSON数据')

3. 处理混合内容与跨域限制

如果支付iframe是HTTPS而你的宿主页面是HTTP(反之亦然),Android 24+默认会阻止混合内容,需要配置:

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
{
    // 根据实际场景选择,优先用NeverAllow如果全是HTTPS
    Control.Settings.MixedContentMode = MixedContentHandling.AlwaysAllow;
}

4. 替换旧版JS执行方式

Android 19+推荐用EvaluateJavascript替代LoadUrl("javascript:..."),避免UI阻塞:

public void ExecuteJs(string script)
{
    if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
    {
        Control.EvaluateJavascript(script, null);
    }
    else
    {
        Control.LoadUrl($"javascript:{script}");
    }
}

5. 避免WebViewClient拦截必要请求

如果自定义了WebViewClient,确保不要拦截iframe的加载请求:

public class PaymentWebViewClient : WebViewClient
{
    readonly HybridWebViewRenderer _renderer;

    public PaymentWebViewClient(HybridWebViewRenderer renderer)
    {
        _renderer = renderer;
    }

    public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request)
    {
        // 仅拦截自定义协议,不要拦截iframe的正常请求
        if (request.Url.Scheme.Equals("appcallback"))
        {
            // 处理自定义协议逻辑
            return true;
        }
        return base.ShouldOverrideUrlLoading(view, request);
    }
}

然后在渲染器里设置:Control.SetWebViewClient(new PaymentWebViewClient(this));

6. 配置混淆与权限

  • 确保AndroidManifest.xml中添加网络权限:<uses-permission android:name="android.permission.INTERNET" />
  • 开启ProGuard混淆时,要保留交互类不被混淆,在proguard-rules.pro中添加:
-keep public class [你的命名空间].HybridWebInterface {
    public *;
}

内容的提问来源于stack exchange,提问作者Timothy Belvin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 07:53:14