uni-app 调用setWebviewclientListener底层循环报错

uni-app 调用setWebviewclientListener底层循环报错

开发环境 版本号 项目创建方式
HBuilderX 3.2.9

产品分类:HTML5+

手机系统:Android

手机系统版本号:Android 10

手机厂商:模拟器

手机机型:模拟器

打包方式:云端

// 自己实现的Java层交互代码,JS调用init方法  
public void init(IWebview iWebview, JSONArray paramJsonArray) {  

    WebView.setWebContentsDebuggingEnabled(true);  
    android.util.Log.d("TestLog", "调用SDK的init方法了,设置监听");  

    // 调用 iWebview.setWebviewclientListener 底层循环报错  
    iWebview.setWebviewclientListener(new CMIDCloudWebviewClientListener() );  
    android.util.Log.d("TestLog", "url = "+iWebview.obtainWebview().getUrl());  

    //  此处代码不生效  
    iWebview.obtainWebview().setWebViewClient(new WebViewClient(){  

        @TargetApi(Build.VERSION_CODES.LOLLIPOP)  
        @Nullable  
        @Override  
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {  
            android.util.Log.d("CoderM", "shouldInterceptRequest");  
            return  WebViewCacheInterceptorInst.getInstance().interceptRequest(request);  
        }  

        @Nullable  
        @Override  
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {  
            android.util.Log.d("CoderM", "shouldInterceptRequest    url");  
            return  WebViewCacheInterceptorInst.getInstance().interceptRequest(url);  
        }  
    });  
    android.util.Log.d("CoderM", "设置完成");  
}

操作步骤:

使用5+形式开发安卓离线SDK 有需求为增加WebView缓存
在JS与java交互代码中拿到了IWebView对象, 最新版本的SDK已经弃用了obtainWebview方法 经测试iWebview.obtainWebview().setWebViewClient(自己实现的WebViewClient类) 无效,shouldInterceptRequest方法不会触发

后自行实现继承于IDCloudWebviewClientListener的一个类,实现shouldInterceptRequestshouldInterceptRequest

预期结果:

正确调用 setWebviewclientListener

实际结果:

底层循环报错

bug描述:

使用5+形式开发安卓离线SDK  有需求为增加WebView缓存,需要拿到webview中的请求内容  
在JS与java交互代码中拿到了`IWebView`对象,  最新版本的SDK已经弃用了`obtainWebview`方法   经测试`iWebview.obtainWebview().setWebViewClient(自己实现的WebViewClient类)` 无效,shouldInterceptRequest方法不会触发  

后自行实现继承于`IDCloudWebviewClientListener`的一个类,实现`shouldInterceptRequest`与`shouldInterceptRequest`

更多关于uni-app 调用setWebviewclientListener底层循环报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html

2 回复

目前webview方式集成已经不再维护,离线打包建议使用默认的方式集成。

更多关于uni-app 调用setWebviewclientListener底层循环报错的实战教程也可以访问 https://www.itying.com/category-93-b0.html


根据你的描述,这是一个典型的5+ SDK原生插件开发问题。核心问题在于setWebviewclientListener的调用方式。

问题分析:

  1. 循环调用问题CMIDCloudWebviewClientListener的实现中,shouldInterceptRequest方法可能被重复触发,形成了递归调用链。这通常发生在:

    • 监听器内部处理逻辑不当
    • 对同一请求进行了多次拦截处理
    • 资源加载过程中触发了新的请求
  2. 版本兼容性:你提到最新SDK已弃用obtainWebview(),这是正确的。5+ SDK的架构设计已经封装了WebView,直接操作原生WebView对象可能导致不可预期的问题。

解决方案:

public class CustomWebviewClientListener implements IDCloudWebviewClientListener {
    
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView webView, String url) {
        // 添加终止条件,避免循环
        if (url == null || url.contains("特定标识")) {
            return null; // 返回null让系统处理
        }
        
        android.util.Log.d("CoderM", "拦截请求: " + url);
        
        // 确保这里不会触发新的网络请求
        WebResourceResponse response = WebViewCacheInterceptorInst.getInstance().interceptRequest(url);
        
        // 如果response为null,必须返回null,否则可能造成循环
        return response;
    }
    
    @Override
    public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest request) {
        if (request == null || request.getUrl() == null) {
            return null;
        }
        
        String url = request.getUrl().toString();
        android.util.Log.d("CoderM", "拦截请求(新API): " + url);
        
        // 同样需要避免循环
        WebResourceResponse response = WebViewCacheInterceptorInst.getInstance().interceptRequest(request);
        
        return response;
    }
    
    // 实现其他必要的方法
    @Override
    public void onPageStarted(WebView webView, String url, Bitmap favicon) {
        // 页面开始加载
    }
    
    @Override
    public void onPageFinished(WebView webView, String url) {
        // 页面加载完成
    }
    
    @Override
    public boolean shouldOverrideUrlLoading(WebView webView, String url) {
        // URL重定向处理
        return false;
    }
}

// 使用方式
public void init(IWebview iWebview, JSONArray paramJsonArray) {
    WebView.setWebContentsDebuggingEnabled(true);
    
    // 正确设置监听器
    iWebview.setWebviewclientListener(new CustomWebviewClientListener());
    
    android.util.Log.d("TestLog", "监听器设置完成");
}
回到顶部