如果WebView页面中链接的标签是target=”_blank”,而你的WebView又没有做任何处理,这个时候就会点击无效的状况,是不是很莫名其妙?
首先看看webview关于窗口打开方式的基本知识:
一、电脑浏览器浏览网页可能会有三种方式:
1.新窗口
2.当前窗口种的新选项卡
3.当前选项卡或者窗口
电脑系统中同一时间可以开启多个相同的进程,就像你可以同时登陆2个qq一样,而在手机中,同一时间只能有一个进程在运行。
在手机中,我们是使用WebView加载网页,虽然浏览器其应用进程只有一个,但是内存中WebView对象可以有多个。在手机上的新窗口就是另外创建一个WebView来加载新的网页。
二、这种关系使得在手机上浏览网页有两种:
1.新选项卡
2.当前选项卡
三、setSupportMultipleWindows与onCreatWindow
1.setSupportMultipleWindows
我们在使用WebView时会首先对其进行初始化
WebSettings webSettings = webView.getSettings();
settings.setDefaultFontSize(16);
settings.setDefaultFixedFontSize(13);
settings.setSupportMultipleWindows(true)
…
再看HTML <a>
标签的 target 属性:
tartget有4个属性:
_blank
浏览器总在一个新打开、未命名的窗口中载入目标文档。
_self
目标文档载入并显示在相同的框架或者目前窗口中作为源文档。
这个目标的值对所有没有指定目标的 <a>
标签是默认目标。这个目标是多余且不必要的,除非和文档标题 标签中的 target 属性一起使用。
_parent
这个目标使得文档载入父窗口或者包含来超链接引用的框架的框架集。如果这个引用是在窗口或者在顶级框架中,那么它与目标 _self 等效。
_top
表示在顶层框架里打开新链接。这个目标使得文档载入包含这个超链接的窗口,用 _top 目标将会清除所有被包含的框架并将文档载入整个浏览器窗口。
另外还可以直接把框架名称指定给target,表示在某个框架也中打开链接,像csdn这样点击左面的目录树,在右边打开新链接就是这种!
setSupportMultipleWindows这个方法是什么意思呢?
setSupportMultipleWindows默认的是false,也就是说WebView默人不支持新窗口,但是这个不是说WebView不能打开多个页面了,只是你点击页面上的连接,当它的target属性是_blank时。它会在当前你所看到的页面继续加载那个连接。而不是重新打开一个窗口。
当你设置为true时,就代表你想要你的WebView支持多窗口,但是一旦设置为true,必须要重写WebChromeClient的onCreateWindow方法。
2.onCreateWindow
下面看看这个方法的签名:
@Override
public boolean onCreateWindow(WebView view, boolean isDialog, boolean isUserGesture, Message resultMsg) {
}
仔细阅读文档,大家应该知道这个参数的意思:
view :请求新窗口的WebView
isDialog : 如果是true,代表这个新窗口只是个对话框,如果是false,则是一个整体的大小的窗口
isUserGesture 如果是true,代表这个请求是用户触发的,例如点击一个页面上的一个连接
resultMsg ,当一个新的WebView被创建时这个只被传递给他,resultMsg.obj是一个WebViewTransport的对象,它被用来传送给新创建的WebView,使用方法:
WebView.WebViewTransport.setWebView(WebView)
返回值:这个方法如果返回true,代表这个主机应用会创建一个新的窗口,否则应该返回fasle。如果你返回了false,但是依然发送resulMsg会导致一个未知的结果。
如果我们仅仅是将WebView嵌入我们自己的应用然后加载网页,很少有必要去设置支持多窗口。只在当前窗口加载新的网页就可。
四、如果非要在新窗口打开,那么需要重写onCreateWindow:
@Override
public boolean onCreateWindow(WebView webView, boolean isDialog, boolean isUserGesture, Message resultMsg) {
X5WebView x5WebView = new X5WebView(activity);
X5WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj;
x5WebView.setWebChromeClient(new CustomWebChromeClient(activity));
x5WebView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//拦截url,跳转新窗口
if (activity != null) {
Intent intent = new Intent(activity, MyWebActivity.class);
intent.putExtra(Constants.INTENT_KEY_URL, url);
activity.startActivity(intent);
}
//防止触发现有界面的WebChromeClient的相关回调
return true;
}
});
transport.setWebView(x5WebView);
resultMsg.sendToTarget();
return true;
}