webview 最全面总结(二)全面介绍 webview 用法
基本使用
下面简单介绍下 WebView 的基本使用:
首先新建一个工程,在 layout 文件里放入一个 WebView 控件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
<WebView
android:id="@+id/webview1"
android:layout_width="match_parent"
android:layout_height="match_parent">
</WebView>
</RelativeLayout>
然后在 Activity 初始化方法里写入如下代码:
String url = "https://www.kkj.cn";
WebView webView = (WebView) findViewById(R.id.web_view);
webView.loadUrl(url);
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
不要忘了在 AndroidManifest 声明访问网络的权限:
<uses-permission android:name="android.permission.INTERNET"/>
然后 bingo 运行,我们会发现,纳尼,居然在外部的默认浏览器中打开了这个链接。
因为默认情况下,一个 WebView 提供的是不像浏览器的控件,没有开启 JavaScript 并且忽略网页错误。如果你的目的是仅仅显示一些 HTML 作为你的 UI 的一部分,那显示可能是没有问题的(显示正常),用户仅仅阅读网页而不需要与之交互,并且网页也不需要和用户交互。
如果你想要在 webview 内部打开,则需要自定义 WebChromeClient 方法。
一般我们重写最多的就是 shouldOverrideUrlLoading()、onPageStarted()、onPageFinished()问题。
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
//webview 页面加载开始时就会执行此方法、一般用作重定向时的初始化工作
//该方法在 WebView 开始加载页面且仅在 Main frame loading(即整页加载)时回调,一次 Main frame 的加载只会回调该方法一次。我们可以在这个方法里设定开启一个加载的动画,告诉用户程序在等待网络的响应。
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//该方法只在 WebView 完成一个页面加载时调用一次(同样也只在 Main frame loading 时调用),我们可以可以在此时关闭加载动画,进行其他操作。
}
});
这样重写之后,我们就能在 webview 里面打开我们想要打开的页面了。然而,我们发现,当我们在我们打开页面的页面中继续跳转时候,再按系统返回键,会发现,直接关闭了 webview,这显然不是我们想要的结果。
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//这是一个监听用的按键的方法,keyCode 监听用户的动作,如果是按了返回键,同时 Webview 要返回的话,WebView 执行回退操作,因为 mWebView.canGoBack()返回的是一个 Boolean 类型,所以我们把它返回为 true
if(keyCode==KeyEvent.KEYCODE_BACK&&webview.canGoBack()){
webview.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
重写返回键之后就能实现,在网页中返回上一步。
详细看一下 webview 的各个知识点。
加载方式
1、loadUrl(String url)
用的最多的加载方式,
des:Load the given url.
as: webView.loadUrl(“http://www.kkj.cn/“); //加载网络网页
webView.loadUrl(“file:///android_asset/html/index.html”); //加载本地 assert 目录下网页
webView.loadUrl(“content://com.Android.htmlfileprovider/sdcard/kris.html”); // 加载 SD 卡 html
2、loadData(String data, String mimeType, String encoding)
des:Load the given data into the WebView.
as:
String summary = “You scored 192 points.”;
webview.loadData(summary, “text/html”, null);
如果后台给的数据是包含 html 的字符串,则需要用这种方式进行加载,这种方式省流量,速度快,但是需要注意编码问题。
loadData()中的 html data 不能包含’#’,’%’,’\’,’?’四种特殊字符
3、loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)
des:Load the given data into the WebView, use the provided URL as the base URL for the content.
webview 的设置
WebSettings webSettings = webview.getSettings();
//支持 js 事件
webSettings.setJavaScriptEnabled(true);
/* 设置为 true 表示支持使用 js 打开新的窗口 */
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
/* 设置为使用 webview 推荐的窗口 */
webSettings.setUseWideViewPort(true);
/* 设置网页自适应屏幕大小 ---这个属性应该是跟上面一个属性一起用 */
webSettings.setLoadWithOverviewMode(true);
/* 设置是否允许 webview 使用缩放的功能,我这里设为 false,不允许 */
webSettings.setBuiltInZoomControls(false);
webSettings.setBuiltInZoomControls(true); //显示或不显示缩放按钮(wap 网页不支持)。
webSettings.setSupportMultipleWindows(true);//设置 WebView 是否支持多窗口。
webSettings.setAppCacheEnabled(true); //启用或禁用应用缓存。
webSettings.setAppCachePath("");//设置应用缓存路径,这个路径必须是可以让 app 写入文件的。该方法应该只被调用一次,重复调用会被无视~
webSettings.setCacheMode(LOAD_DEFAULT);//用来设置 WebView 的缓存模式。当我们加载页面或从上一个页面返回的时候,会按照设置的缓存模式去检查并使用(或不使用)缓存。
篇幅限制,仅列了一些最常用的设置,webview 还可以设置更多内容,存储,默认字体大小,默认字符编码等等,
具体可以参考,史上最全的WebSettings说明
对于 webview 也有
webView.setHorizontalScrollBarEnabled(false);
//水平不显示
webView.setVerticalScrollBarEnabled(false); //垂直不显示
webView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);// 隐藏滚动条
webView.requestFocus(); 设置是否获取焦点
webView.requestFocusFromTouch();
WebViewClient
主要帮助 WebView 处理各种通知、请求事件(例如,点击链接时候如何显示界面,页面开始加载,加载完毕之后
webview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
//webview 页面加载开始时就会执行此方法、一般用作重定向时的初始化工作
//该方法在 WebView 开始加载页面且仅在 Main frame loading(即整页加载)时回调,一次 Main frame 的加载只会回调该方法一次。我们可以在这个方法里设定开启一个加载的动画,告诉用户程序在等待网络的响应。
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//该方法只在 WebView 完成一个页面加载时调用一次(同样也只在 Main frame loading 时调用),我们可以可以在此时关闭加载动画,进行其他操作。
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
// 这里进行无网络或错误处理,具体可以根据 errorCode 的值进行判断,
}
shouldOverrideUrlLoading()方法分析
从实践中我们知道,当我们没有给 WebView 提供 WebViewClient 时,WebView 如果要加载一个 url 会向 ActivityManager 寻求一个适合的处理者来加载该 url(比如系统自带的浏览器),这通常是我们不想看到的。于是我们需要给 WebView 提供一个 WebViewClient,并重写该方法返回 true 来告知 WebView url 的加载就在 app 中进行。这时便可以实现在 app 内访问网页
简单来说就是:
1、若没有设置 WebViewClient 则在点击链接之后由系统处理该 url,通常是使用浏览器打开或弹出浏览器选择对话框。
2、若设置 WebViewClient 且该方法返回 true ,则说明由应用的代码处理该 url,WebView 不处理。
3、若设置 WebViewClient 且该方法返回 false,则说明由 WebView 处理该 url,即用 WebView 加载该 url。
WebChromeClient
===============
辅助 WebView 处理 Javascript 的对话框、网站图标、网站 Title、加载进度等
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
// 获得网页的加载进度 newProgress 为当前加载百分比
super.onProgressChanged(view, newProgress);
}
@Override
public void onReceivedTitle(WebView view, String title) {
// 获取网页的 title,客户端可以在这里动态修改页面的 title
// 另外,当加载错误时 title 为“找不到该网页”
super.onReceivedTitle(view, title);
}
});
js 的交互
webView.addJavascriptInterface()
通过 addJavascriptInterface(Object, String)方法注入 Java 对象到 WebView。这个方法允许你注入一个 Java 对象到网页的 JavaScript 的上下文,以便通过页面中的 JavaScript 调用。
简单粗暴时候可以这样写:
myWebView.addJavascriptInterface(new JSInterface(){
@JavascriptInterface
public String methodA(){
return ((TelephonyManager) getSystemService(TELEPHONY_SERVICE)).getDeviceId();
}
@JavascriptInterface
public void methodB(String webMessage) { }
}, "Android");
方法可能会很多,所以我们要学会优雅一些;
mWebView.addJavascriptInterface(new JSInterface(), "Android"); //model 是自定义的,随便起。
JSInterface 对象:
public class JSInterface {
@JavascriptInterface
public void methodA() { }
@JavascriptInterface
public void methodB(String webMessage) { }
}
ps:SDK>=17(Android4.2)以上,必须添加 @JavascriptInterface 声明,为避免因用户访问不安全网页导致 js 漏洞盗窃用户信息等不安全行为。
js 调 java:
Java 对象到 WebView 之后,我们要在 js 里面调用 java 方法。
所有调用的方法都要写在 class JSInterface{ }中。
funtion a{
winow.Android.methodA(); //可带参数
}
java 调 js:
在 webview 里面调用 js 方法:
webview.loadUrl("javascript:alert()");
前进后退刷新
webview 是否可以返回到上一页面 webView.canGoBack()
评论