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进行处理

Android  WebView控件的使用进阶_android

代码:

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>