一、场景
App基于webview混合开发,业务主要为前端h5实现,其中有一个功能为消息中心,当从通知栏点击消息跳转到指定页面时,前端会不停地刷新页面,一遍又一遍地重复同一批请求。
二、问题分析
1、刚开始怀疑是否前端里面调用了reload 或者 框架提供的刷新接口,在反复刷新页面,通过沟通排查确认没有。并且自己将框架里面所有的刷新接口都注释掉,情况依然出现,所以此原因排除。
2、当正常打开App从对应菜单进入到改跳转页面时,都是正常的,不会出现反复刷新请求,只有从消息跳转进入才会,因为怀疑是否为使用Intent 跳转Activity 问题,然后经过排查调试代码,发现这个点也非问题原因。
3、苹果端无此问题,聚焦安卓端webview回调分析
定位到 shouldOverrideUrlLoading 方法, 发现自己的代码为如下写法:
public boolean shouldOverrideUrlLoading(final WebView view, final String url)
{
view.loadUrl(url);
return true;
}
在网上查阅一番:
webview中shouldOverrideUrlLoading方法解析-CSDN博客
发现这个写法是错误的,
/**
* Give the host application a chance to take control when a URL is about to be loaded in the
* current WebView.
* 给宿主应用一个机会去控制在当前webview即将加载的一个url。
*
* If a WebViewClient is not provided, by default WebView will ask Activity
* Manager to choose the proper handler for the URL.
* 如果没有提供(自定义创建)WebViewClient,通过默认的webview会要求Activity Manager去处理当前URL。(补充:通常是系统浏览器)
*
* If a WebViewClient is provided,returning
* 如果提供了(自定义创建设计)WebViewClient
*
* {@code true} causes the current WebView to abort loading the URL, while returning
* 返回true会导致当前webview中止加载url,
*
* {@code false} causes the WebView to continue loading the URL as usual.
* 返回false会导致webview正常继续加载url。
*
* Do not call {@link WebView#loadUrl(String)} with the request's
* URL and then return {@code true}.
* 不要调用loadUrl方法并且返回true。
*
* The correct way to continue loading a given URL is to simply
* return {@code false}, without calling {@link WebView#loadUrl(String)}.
* 继续加载url的正确的做法就是简单的返回false即可,不需要调用loadUrl方法。
*/
根据接口说明,只有当拦截某些需要特殊处理的请求时,需要增加判断然后返回true, 否则直接返回false, 会调用父类中的类处理。 而此处直接使用view.loadUrl 方式加载了一次,可能就是导致无线循环刷新页面的原因,当将此处代码调整后,果然这个问题解决了。
后续再回想当时为何这么写,已然不是太记得了,可能是当时为了防止请求直接调用手机中的浏览器?
另外此问题只在特定项目的App前端里面才出现,原因就是只有那个项目的前端在点击消息跳转时才会触发这个回调方法,其他地方都不会触发这个,包括此项目的正常进入此菜单页面,也不会触发,所以对于这个触发条件现在也不太清楚,需要后续有时间再和前端一起确认,项目催得急着解决问题,先就这样吧。