webview使用进阶
WebViewClient
WebViewClient是webview的一个辅助类,我们经常使用WebViewClient这个类来监控webview加载网页的状态。
下面的是我们在开发中经常会使用的方法。
- onLoadResource
网页加载网页各种资源的回调,比如你的网页使用了各种图片和css文件与js文件 - onPageStarted
网页开始加载的回调 - onPageFinished
网页加载完成的回调 - onReceivedError(WebView view, int errorCode, String description, String failingUrl)
网页加载失败的回调,如果是运行在6.0的手机,需要onReceivedError(WebView, WebResourceRequest, WebResourceError) - shouldOverrideUrlLoading
处理网页内部的跳转
WebChromeClient
处理js交互与网页内容的类
- onJsAlert
接收网页的alert事件 - onJsPrompt
接收网页的prompt输入框事件 - onJsConfirm
接收网页的confirm确认事件 - onProgressChanged
页面加载的百分比 - onReceivedIcon
接收网页的图标 - onReceivedTitle
接收网页的标题
WebSettings
webview的设置类,能够设置webview的各种详细参数
- setAllowFileAccess(boolean allow)
设置是否使用file协议访问网页,常用于访问assets与raw文件夹下面的网页 - setBuiltInZoomControls(boolean enabled)
设置是否使用webview自带的缩放功能 - setDatabaseEnabled(boolean flag)
- setDomStorageEnabled(boolean flag);
设置是够支持html5的数据库功能 - setDefaultFontSize(int size)
设置页面的文字大小 - setJavaScriptEnabled(boolean flag)
设置是否执行页面的js方法 - setCacheMode
设置返回键的处理,是否使用缓存加载页面,LOAD_DEFAULT(先从cache加载,没有再去网络加载), LOAD_CACHE_ELSE_NETWORK(先从cache加载,没有再去网络加载), LOAD_NO_CACHE(不使用cache) , LOAD_CACHE_ONLY(只使用cache)
WebView
android提供的控件,能够加载网页和html数据。
- addJavascriptInterface(Object object, String name)
在使用的时候如果js要调用Java里面的方法的话要在方法上面添加一个注解
@JavascriptInterface
该注解如果不添加的话在JavaScript里面就找不到该方法
增加一个对象使webview能够让java代码与js交互
- loadUrl(String url)
加载一个网页,能够是网络的网页,也能加载本地的网页,本地的网页使用(file:///android_asset/)来加载。也可以调用一个javaScrpit方法。 - loadData(String data, String mimeType, String encoding)
- loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl)
加载一段html代码 - reload()
刷新当前页面 - getTitle()
获取当前页面的标题 - canGoBack()
- goBack()
判断webview是否能够回到上一步
使用WebView需要注意的问题
在android 4.2版本以下的手机有一个问题就是,webview会被JavaScript注入,造成手机出现信息安全的问题,比如下载病毒,发送短信等等。问题就出在addJavascriptInterface方法。JavaScript通过调用这个接口可以直接操作本地的JAVA接口。
google在4.2的版本上面解决了这个问题,解决的方法是在被js调用的方法上面加上一个声明, @JavascriptInterface ,但是4.2版本以下的手机就没有提出官方的解决方法。目前来说在4.2版本以下的手机能够采用以下几个方法来解决安全问题
- 1 通过自定义url来进行通信,我们可以重写 shouldOverrideUrlLoading 方法来接收参数
- 2 通过js通过prompt方法传递参数到 onJsPrompt
- 1 onJsAlert->JavaScript->alter
- 2 onJsPrompt ->JavaScript->prompt->java返回一个参数给js
- 3 onJsConfirm ->JavaScript->Confirm->java返回一个参数给js
- 4 addJavascriptInterface->4.2以下的手机->@JavascriptInterface
- 5 url跳转->shouldOverrideUrlLoading->根据url进行处理
代码:
MainActivity.java
package view.webviewtest.com.webviewtest;
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private WebView webView;
private ImageView imageView;
//传输java对象过去
//@SuppressLint("JavascriptInterface")
@SuppressLint("JavascriptInterface")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.webView);
// imageView = findViewById(R.id.image);
//表示允许加载本地的文件
webView.getSettings().setAllowFileAccess(true);
//使用WebView控件支持JavaScript
webView.getSettings().setJavaScriptEnabled(true);
//该方法用于接听Web状态
// 我们经常使用WebViewClient这个类来监控webview加载网页的状态。
webView.setWebViewClient(new WebViewClient(){
//在WebView控件中如果点击的话他会自动跳转到系统自带游览器里面
//表示 发生重定向我们自己处理 就是页面的跳转 url表示获取点击的路径
//处理网页内部的跳转
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// Log.v("liwangjiang","url="+url);
view.loadUrl(url);
return true;
}
// onLoadResource方法 网页加载网页各种资源的回调,比如你的网页使用了各种图片和css文件与js文件
//就是加载网页的一些图片资源等等....
@Override
public void onLoadResource(WebView view, String url) {
//Log.v("liwangjiang","url="+url);
super.onLoadResource(view, url);
}
//网页开始加载的回调
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
//Log.v("liwangjiang","开始加载");
super.onPageStarted(view, url, favicon);
}
//onPageFinished页面加载完成的时候 回调
@Override
public void onPageFinished(WebView view, String url) {
//Log.v("liwangjiang","加载完成");
super.onPageFinished(view, url);
}
//onReceivedError网页加载失败的回调,如果是运行在6.0的手机,需要
//errorCode文件的错误代码
//description 文件的状态
//failingUrl文件的路径
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
// Log.v("liwangjiang","errorCode = "+errorCode);
// Log.v("liwangjiang","description = "+description);
// Log.v("liwangjiang","failingUrl = "+failingUrl);
super.onReceivedError(view, errorCode, description, failingUrl);
}
//允许在6.0的手机
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
// Log.v("liwangjiang","6.0手机");
super.onReceivedError(view, request, error);
}
});
//该设置用于监听JavaScript代码进行交互
webView.setWebChromeClient(new WebChromeClient(){
//onJsAlert用于和JS里面的Alert对话框进行交互
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//url表示传输协议 和路径
// Log.v("liwangjiang","url = "+url);
// message表示提示框里面的信息
// Log.v("liwangjiang","message = "+message);
// if(message.equals("run click")){//js更java代码进行交互比如
show(message);//可以通过alert调用JAVA方法
// }
//如果不设置该方法就表示只能使用一次 设了 就可以显示多次
//该方法表示提交数据直接按下确认键 里面的参数表示提交的内容
result.confirm();
//返回就是在网页上面捕获窗口在不要让窗口显示
return true;
}
//onJsPrompt接收网页的prompt输入框事件
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
//onJsPrompt一般和onJsAlert联合使用
// Log.v("liwangjiang","url = "+url);//表示路径
//Log.v("liwangjiang","message = "+message);//对话框输入的内容 prompt("abc","def");
//Log.v("liwangjiang","defaultValue = "+defaultValue);//默认值 prompt("abc","def");
//该方法表示提交数据直接按下确认键 里面的参数表示提交的内容
result.confirm("run click");//提交一个run click的字符串让onJsAlert捕获接收调用java代码
return true;
}
//接收网页的confirm确认事件 主要用于接收确认事件
// @Override
// public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
// // Log.v("liwangjiang","message = "+message);
// result.confirm();
// return true;
// }
//onProgressChanged页面加载的百分比
//该方法用于接听网页的进度条 newProgress表示当前进度
@Override
public void onProgressChanged(WebView view, int newProgress) {
// Log.v("liwangjiang","newProgress = "+newProgress);
super.onProgressChanged(view, newProgress);
}
//onReceivedIcon
//接收网页的图标就是一个网页的标题旁边的图片
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
// imageView.setImageBitmap(icon);
super.onReceivedIcon(view, icon);
}
//onReceivedTitle
//接收网页的标题 接收标题
@Override
public void onReceivedTitle(WebView view, String title) {
// Log.v("liwangjiang","title = "+title);
super.onReceivedTitle(view, title);
}
});
//getSettings方法的使用
//设置是否使用webview自带的缩放功能
webView.getSettings().setBuiltInZoomControls(true);
//setDefaultFontSize设置页面的文字大小
//webView.getSettings().setDefaultFontSize(50);
//设置返回键的处理,是否使用缓存加载页面,LOAD_DEFAULT(先从cache加载,没有再去网络加载), LOAD_CACHE_ELSE_NETWORK(先从cache加载,没有再去网络加载), LOAD_NO_CACHE(不使用cache) , LOAD_CACHE_ONLY(只使用cache)
// webView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
//增加一个对象使webview能够让java代码与js交互
//object表示那个对象里面的里面的方法
//name 表示提供一个名字给js 在js里面调用是
//window.obj.javaScriptCodeCall("javaScript调用Java代码");
webView.addJavascriptInterface(this,"demo"); //在使用过程中一定要写一个注解
//改变标题
webView.getTitle().replace("","");
//判断webview是否能够回到上一步
webView.goBack();
//加载一个网页,能够是网络的网页,也能加载本地的网页,本地的网页使用(file:///android_asset/)来加载。也可以调用一个javaScrpit方法。
//加载网站
//webView.loadUrl("http://www.qq.com/");
//file:当前项目文件目录
//android_asset 找到 assets文件
webView.loadUrl("file:///android_asset/my.html");
}
public void show(String content){
Toast.makeText(this,content+"",Toast.LENGTH_SHORT).show();
}
//在javaScript里面调用的方法
@JavascriptInterface
public void inPutOne(String name){
Toast.makeText(this,name,Toast.LENGTH_SHORT).show();
}
public void onClick(View view){
//java代码调用JS代码
webView.loadUrl("javascript:changeImage01()");
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/webView">
</WebView>
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
android:onClick="onClick"/>
<!--<ImageView-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:id="@+id/image"/>-->
</RelativeLayout>
my.html
<html>
<head>
<script language="javascript">
function changeImage02() {
document.getElementById("image").src="Lin.jpg";
}
function changeImage01() {
document.getElementById("image").src="Lint.png";
}
function gotourl(){
window.location ="http://www.qq.com";
// window.location ="api:end";
}
function showpro(){
var name = prompt("abc","def");
alert(name);
}
function show(){
alert("run click");
}
function disp_confirm(){
var r=confirm("是否结婚");
if (r==true){
alert("已婚");
}
else{
alert("为婚");
}
}
function callJavaCode(){
window.demo.inPutOne("I On Click a");//
}
function gotoMethed(){
window.location ="success:512";
}
</script>
</head>
<body bgcolor="red">
<a onClick="callJavaCode()">
<img id="image" src="ic_launcher.png"/></a>
</body>
</html>