Search code examples
androidandroid-webviewandroid-api-levelsandroid-min-sdk

shouldInterceptRequest called twice for deprecated and non deprecated variant when using non deprecated


I have webView which overrides shouldInterceptRequest method:

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
    WebResourceResponse response = proxy.getWebResourceResponse(request.getUrl(), request.getMethod(), request.getRequestHeaders());
    if (response == null) {
        return super.shouldInterceptRequest(view, request);
    } else {
        return response;
    }
}

@SuppressWarnings("deprecation")
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
    WebResourceResponse response = proxy.getWebResourceResponse(Uri.parse(url), "GET", null);
    if (response == null) {
        return super.shouldInterceptRequest(view, url);
    } else {
        return response;
    }
}

The problem is that on Lollipop+ both methods are called. So I think that I should specify that deprecated version should be used only for old Android version. Exactly inverse of RequiresApi... If cause that can be solved with making copy paste classes and using if-else to choose class depending on Android version... But that's really ugly.

UPDATE. Updated to better reflect the problem.


Solution

  • The default implementation of WebViewClient in Android source codes invokes the deprecated version of shouldInterceptRequest from the newer one, passing current URL from the request as a string:

    @Deprecated
    public WebResourceResponse shouldInterceptRequest(WebView view, String url)
    {
        return null;
    }
    
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)
    {
        return shouldInterceptRequest(view, request.getUrl().toString());
    }
    

    Since you call the default Lollipop-specific handler from your custom WebViewClient implementation (using super.shouldInterceptRequest(view, request) when request is null), it invokes, in turn, your overriden implementation of the deprecated handler.

    You should not call the super method from your new implementation in order to eliminate the deprected method execution.