WebView在加载无效链接时未调用shouldOverrideUrlLoading()方法

24

HTML文件中有两种类型的链接:

(1) A normal link like http://www.bbb.com/q?type=normal
(2) A short link like /q?type=short.

对于第一种,请直接载入URL。对于第二种,我需要在载入URL之前添加一个固定地址,例如http://www.abc.com

我正在尝试通过覆盖WebViewClient中的shouldOverrideUrlLoading()函数来实现此操作。然而,对于第二种链接,该函数不会被调用。我尝试在HTML文件中将"http://www.abc.com"添加到第二种链接中。然后,当我点击第二种链接时,函数确实被调用了。

我认为发生的情况是,WebView首先会检查链接是否是有效的URL。只有在它是有效的情况下,这个函数才会被调用。我对吗?我该如何解决这个问题?提前感谢您的帮助。

        contentWebView = new WebView(context);

        webViewClient = new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // String not in Logger.
                Log.d(TAG, "Here!");
                Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                context.startActivity(intent);
                return true;
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                if (hosted) {
                    contentWebView.setVisibility(VISIBLE);
                } else {
                    summaryTextView.setVisibility(VISIBLE);
                    articleLinkButton.setVisibility(VISIBLE);
                }

                progressBar.setVisibility(View.GONE);
            }
        };

        contentWebView.setWebViewClient(webViewClient);
        contentWebView.getSettings().setJavaScriptEnabled(true);
        contentWebView.loadData(fullString, "text/html", "utf-8");
        contentWebView.setVisibility(GONE);

更多内容:

我尝试修改

contentWebView.loadData(fullString, "text/html", "utf-8");
contentWebView.loadDataWithBaseURL("http://www.abc.com", fullString, "text/html", "utf-8", null);

然后该函数被调用。

如果我手动将html字符串中的短链接更改为完整链接,则该函数也会被调用。

因此,我认为可能是这样发生的:WebView检查链接URL是否有效。只有在URL有效时,才会调用shouldOverrideUrlLoading()函数。


你能展示一下你的shouldOverrideUrlLoading()实现的代码吗? - shkschneider
@shkschneider 代码已添加。但问题是如果URL无效,则该函数不会被调用。 - darklord
请注意,在您进行编辑后:是的,这正是发生的事情。尝试提供一个baseUrl。 - shkschneider
6个回答

12
您可能正在使用KitKat WebView。 这是一个已知问题(我认为在迁移指南中有概述),其中不能针对基本URL解析的URL被丢弃(您将不会收到任何回调,无论是shouldOverrideUrlLoading还是onPageStarted)。
问题在于您的基本URL是数据URL,因此您试图针对“data:text / html,...”解析“/ q?type = short”,这在很大程度上没有意义,因此整个尝试导航到URL被忽略。
这与pre-KK WebView不同,后者使用KURL而不是GURL进行URL处理。 GURL通常比KURL更严格(和更安全),这是两个WebView版本之间某些不兼容性的原因。

1
迁移指南:https://developer.android.com/guide/webapps/migrating.html - Beth Mezias

10

7
我遇到的解决方案是使用loadDataWithBaseURL,将baseUrl设置为无效的值,并在setWebViewClient中检测并将其替换为“http://”。
public class MyActivity
    extends Activity
{
    private static final String badurl = "http://myappname.invalid/";

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        ...
        WebView wv = ((WebView)findViewById(R.id.webview));
        WebSettings settings = wv.getSettings();
        settings.setJavaScriptEnabled(false);
        settings.setSupportMultipleWindows(true);
        wv.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg)
            {
                handleUrlview.getHitTestResult().getExtra());
                return true;
            }
        });
        wv.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) 
            {
                handleUrl(url);
                return true;
            }
        });
        wv.loadDataWithBaseURL(badurl,text,"text/html","utf-8",null);
    }

    private void handleUrl(String url)
    {
        if (url.startsWith(badurl))
            url = "http://"+url.substring(badurl.length());
        try {
            startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
        } catch (ActivityNotFoundException e) { }
    }
}

0

我也遇到了这个问题,并通过替换我的HTML响应来解决它。在我的HTML响应中,“href” HTML标记中没有任何主机。然后,我用以下代码替换它,现在它像魔法一样正常工作:)

        String htmlString = AppCache.homePageResponse.showcaase.replace("href=\"/", "href=\"" + "evidea://" );

-1

使用target="_top"与iframe。 - sharma.mahesh369

-2

试试这个

 private static WebView webView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main); //should be activity_main

        webView = (WebView) findViewById(R.id.web);

        webView.setWebViewClient(new webviewclient());
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl("http://www.yahoo.com");

    }
public class webviewclient extends WebViewClient{

    @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        view.loadUrl(request.toString());
        return true;
    }


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接