Hybrid开发中如何拦截WebView的URL跳转?

娇娇🍀 阅读 9

我在做Hybrid App,用的是Android WebView加载H5页面。现在想在H5里点击链接时,由原生层拦截处理某些特定协议的URL(比如 myapp://action),但试了 shouldOverrideUrlLoading 好像没生效,有的链接还是直接在WebView里打开了。

我加了判断前缀的逻辑,但有时候拦截不到,是不是哪里写错了?相关代码大概是这样:

public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (url.startsWith("myapp://")) {
        handleCustomScheme(url);
        return true;
    }
    return false;
}
我来解答 赞 6 收藏
二维码
手机扫码查看
1 条解答
Mr.斐然
Mr.斐然 Lv1
这个问题大概率是API兼容性问题。从Android N(API 24)开始,shouldOverrideUrlLoading的方法签名变了,新方法接受WebResourceRequest参数,旧方法接受String参数。如果你只重写了旧方法,在API 24+的设备上可能不会被调用。

按照官方文档的说明,正确的做法是同时重载两个方法,确保兼容性。给你一段规范写法:

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// API 24 以下走这里
return handleUrl(url);
}

@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
// API 24 以上走这里
return handleUrl(request.getUrl().toString());
}

private boolean handleUrl(String url) {
if (url.startsWith("myapp://")) {
handleCustomScheme(url);
return true;
}
return false;
}


另外还有几个坑要注意一下。第一是302/301重定向问题,有些链接会服务端重定向,这种情况下shouldOverrideUrlLoading可能只会在最终URL触发,中间过程拦截不到。第二是JavaScript触发的跳转,比如window.location.href,这个在大部分情况下能拦截到,但有些极端情况需要配合WebViewClient的其他方法处理。

按照规范,建议把自定义协议的判断逻辑抽出来单独处理,方便维护。还有一点,如果你的H5页面里有iframe,iframe内部的跳转也可能触发这个方法,记得做好容错。

实测下来,上面的写法能覆盖绝大多数场景。如果还有漏网之鱼,可能需要检查一下是不是页面用了什么奇怪的跳转方式,比如meta refresh之类的。
点赞 1
2026-03-01 02:01