WebView问题系列:
1.
2.
1.遇到的问题-基本使用
- 用应用内部的WebView打开url时的错误概念
场景还原:以往一直认为使用应用内部的WebView而不是系统的WebView打开url时,需要使用以下代码:
WebViewClient myWebClient=new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
};
查阅谷歌的说明才知道,
Give the host application a chance to take control when a URL is about to be loaded in the current WebView.
If a WebViewClient is not provided, by default WebView will ask Activity Manager to choose the proper handler for the URL.
If a WebViewClient is provided, returning true causes the current WebView to abort loading the URL,
while returning false causes the WebView to continue loading the URL as usual.
翻译过来的意思就是:
这个方法给了宿主应用接管即将被当前webview加载的url的机会
如果没有WebViewClient提供,那默认的WebView会请求Activity管理者选择你一个合适的处理程序来处理这个url(系统浏览器或选择浏览器的弹框)
如果有WebViewClient,并且shouldOverrideUrlLoading方法返回了true则会导致当前的webView停止加载此url,
而返回false的话,则当前的webView正常加载这个url
所以,上面1的写法并不标准,并不一定要以上写法,下面写法同样可以达到效果
WebViewClient myWebClient=new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
};
或者:
webView.setWebViewClient(new WebViewClient);
- ERROR_NO_URL_SCHEME出现
场景复现:尝试使用WebView去加载"",WebViewClient代码如下:
WebViewClient myWebClient=new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
};
当点击其中某一个链接时(并不是所有链接),弹出以下错误:
ERROR_NO_URL_SCHEME
WebViewClient myWebClient = new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url == null) return false;
try {
if (url.startsWith("http") || url.startsWith("https")) {
view.loadUrl(url);
return true;
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
} catch (Exception e) { //uri 匹配不到的情况
return true;
}
}
};
- shouldOverrideUrlLoading解析
针对以上两个问题,均是shouldOverrideUrlLoading该方法的使用上导致的,下面仔细看下这个方法的细节
1.方法解释:
image.png
1.执行时机
从当前的验证来看,如果加载的ur需要重定向,那么该方法一定会被调用:
比如我用url加载:""后,就会调用此方法,因为""会被重定向到""
判断重定向的代码:
new Thread(new Runnable() {
@Override
public void run() {
try {
URL url = new
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setReadTimeout(5000);
urlConnection.setConnectTimeout(5000);
int responseCode = urlConnection.getResponseCode();
Log.e("test", "responseCode-->" + responseCode);
} catch (Exception e) {
Log.e("test", "exception--->" + e.getMessage());
}
}
}).start();
结果:
01-31 14:38:13.869 31170-31288/com.example.cuixm.ticketquery E/test: responseCode-->302
WebViewClient,只是加了一句log:
WebViewClient myWebClient = new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.e("test","shouldOverrideUrlLoading-->"+url);
if (url == null) return false;
try {
if (url.startsWith("http") || url.startsWith("https")) {
view.loadUrl(url);
return true;
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
}
} catch (Exception e) { //uri 匹配不到的情况
return true;
}
}
};
结果:
01-31 14:38:13.978 31170-31170/com.example.cuixm.ticketquery E/test:
2.使用方法
也就是当应用想要劫持即将要加载的url时,可以为当前webView设置
一个新的WebViewClient然后复写shouldOverrideUrlLoading此方法,
然后,针对具体的url在做针对性的逻辑