包含IFRAME内部超链接的Android webview无法正常工作

时间:2013-09-06 15:31:25

标签: android iframe webview hyperlink

嵌入Android WebView时,此示例中的超链接无效。有人可以解释为什么以及如何纠正它?它在桌面Chrome浏览器中运行良好。下面提供的示例HTML代码是从twitter时间线小部件生成的动态代码中复制的。我无法控制Twitter时间线小部件创建的HTML,因此我需要一个解决此限制的解决方案。

以下是设置示例:

的test.html:

<iframe src="twitter.html"></iframe>

twitter.html:

<a href="http://t.co/zCcFf1SWtL" target="_blank" class="link media customisable" data-pre-embedded="true" dir="ltr">pic.twitter.com/zCcFf1SWtL</a>

Java代码:

webView.loadUrl("file:///android_asset/test.html");

实际的Twitter时间轴小部件HTML :(这会注入上面的HTML代码)

<a class="twitter-timeline" height="355" data-dnt="true" href="https://twitter.com/VectrenStorm" data-widget-id="367009971554095104">Tweets by @VectrenStorm</a>
!function (d, s, id) { var js, fjs = d.getElementsByTagName(s)[0], p = /^http:/.test(d.location) ? 'http' : 'https'; if (!d.getElementById(id)) { js = d.createElement(s); js.id = id; js.src = p + "://platform.twitter.com/widgets.js"; fjs.parentNode.insertBefore(js, fjs); } } (document, "script", "twitter-wjs");

1 个答案:

答案 0 :(得分:3)

显然这是Android WebView的限制。当IFRAME内的超链接上的target =“_ blank”时,单击链接时,ShouldOverrideUrlLoading 未被调用

作为一种解决方法,我实现了一个新的WebChromeClient类并覆盖了onCreateWindow方法。单击链接时会触发此方法;在onCreateWindow中我创建一个新的临时webview并将其分配给WebViewTransport消息,然后返回true。我还为新的WebView分配了一个WebViewClient的自定义实现。创建新的webview时,会触发ShouldOverrideUrlLoading方法。在ShouldOverrideUrlLoading方法中,我在原始webview上加载调用loadUrl,然后销毁新的临时webview。

这是一些代码(用C#/ mono编写):

public class TwitterChromeClient : WebChromeClient
{
    public override bool OnCreateWindow(WebView view, bool dialog, bool userGesture, Android.OS.Message resultMsg)
    {
        WebView newWebView = new WebView(view.Context);
        newWebView.SetWebViewClient(new TempWebClient(view));
        WebView.WebViewTransport transport = (WebView.WebViewTransport)resultMsg.Obj;
        transport.WebView = newWebView;
        resultMsg.SendToTarget();
        return true;
    }
}

public class TwitterWebClient : WebViewClient
{
    public override bool ShouldOverrideUrlLoading(WebView view, string url)
    {
        //Unfortunately this method will never be called for links inside an iframe when target="_blank"
        return true;
    }
}

public class TempWebClient : WebViewClient
{
    public WebView OriginalWebView { get; set; }

    public TempWebClient(WebView originalWebView)
    {
        OriginalWebView = originalWebView;
    }

    public override bool ShouldOverrideUrlLoading(WebView view, string url)
    {
        OriginalWebView.LoadUrl(url);
        OriginalWebView = null;
        view.Destroy();
        return true;
    }
}