Android 入门第八讲01-WebView(WebView概述,基本用法(加载远程网页,加载本地网页),进阶用法(前进返回,清除缓存,网页自适应屏幕,缩放),WebView的三个子类)

1.WebView概述-加载网页

Android里面有很多页面,是可以用网页来写的,通过我们学习的web,写成html网页,来充当安卓中的一个页面,其实在我们很多应用程序里都用到了WebView,例如我们的公众号,小程序,很多的页面都不是用安卓来写的,其实是加载了一个网页。
1.Android WebView在Android平台 上是一个特殊的View, 它能用来显示网页,这个WebView类可以被用来在app中仅仅显示一张在线的网页,当然还可以用来开发浏览器。

2.WebView内部实现是采用渲染引擎(WebKit)来展示view的内容,提供网页前进后退、网页放大、缩小、搜索等功能。

3.WebView是一个基于webKit引擎. 展现Web页面的控件, Androi d的WebView在低版本和高版本采用了不同的webKit版本内核。

4.Android的Webview在低版本和高版本采用了不同的webkit版本内核, 4.4后直接使用了Chrome.

WebView的优处

1.节省工作量,节约人力成本

打个比方,假设我们要写一个登录功能,对于不同系统ios和Android的话就要写两种登录方式,但是通过写一个网页然后再用webview来加载的话就只需要写一个登录界面,也就是说减少了一半的工作量

2.开发的内容可以动态修改

我们用安卓写的应用程序,安装在用户手机以后,那些控件就不能进行修改了,除非更新重新安装新的版本应用程序,但是我们的WebView,只需要修改网页上的内容,用户在下一次加载就可以更新页面内容,就例如我们在腾讯新闻,每天可以在同一个控件里却可以看到不同的新闻,

WebView的缺处
1.web网页的写法比安卓的写法慢(大概慢30%)

2.WebView的基本用法

第一步,添加权限

在mainifests里添加权限代码

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

在<application结点下添加

		android:usesCleartextTraffic="true"

在这里插入图片描述

第二步,添加控件

布局文件中添加WebView控件

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/webview"
      android:layout_width="match_parent"
      android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

第三步,获取网页

1.加载远程网页

1.一般网页

public class MainActivity extends AppCompatActivity {


    WebView mWebView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mWebView=findViewById(R.id.webview);
        mWebView.loadUrl("https://me.csdn.net/qq_46526828");
    }
}

在这里插入图片描述

2.特殊网页(会调用系统浏览器)

我们看这样一个例子
在这里插入图片描述

我们可以发现,我们的应用程序并没有加载网页,而是调用了系统的浏览器去加载这个网页

解决方法:我们可以通过重写shouldOverrideUrlLoading这个方法来使网页在程序内加载


public class MainActivity extends AppCompatActivity {


    WebView mWebView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mWebView=findViewById(R.id.webview);


      mWebView.loadUrl("http://jd.com");
      mWebView.setWebViewClient(new WebViewClient(){
          @Override
          public boolean shouldOverrideUrlLoading(WebView view, String url) {
              view.loadUrl(url);
              return true;
          }
      });
    }
}

在这里插入图片描述

2.加载本地网页

这里因为是使用本地数据,所以传入的url需要做些处理,例如:
a.如果html文件存于assets:则加前缀:file:///android_asset/
b.如果html文件存于data/data/包名目录:则加前缀:file:///data/data/包名/

1.assets目录

第一步,创建Assets文件夹
在这里插入图片描述
第二步,创建 test.html 页面文件在这里插入图片描述
编写网页

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">//自适应屏幕
    <title>Document</title>
</head>
<body>
<h1>标题1</h1>
<h2>标题2</h2>
<div>div content</div>
</body>
</html>

在这里插入图片描述

第三步,加载本地网页


public class MainActivity extends AppCompatActivity {


    WebView mWebView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mWebView=findViewById(R.id.webview);

        mWebView.loadUrl("file:///android_asset/test.html");
    }
}

在这里插入图片描述
修改运行
在这里插入图片描述

2.data/data/包名目录

第一步,复制之前assets文件的路径(按住ctrl+左键进入文件位置)
在这里插入图片描述第二步,将文件上传到data/data/包名 目录
在这里插入图片描述

为什么要这样添加?因为复制粘贴没用,我试了嘿嘿

第三步,加载网页

public class MainActivity extends AppCompatActivity {
    WebView mWebView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mWebView=findViewById(R.id.webview);
        

      mWebView.loadUrl("file:///data/data/com.c201801020224.myapplication/test.html");
    }
}

在这里插入图片描述

我们用的比较多的本地加载页面通常是第二种方法,因为第一种方法会随着我们的apk一起打包给用户,而第二种方法是只有用户需要使用时,才会远程的去下载这个网页文件,所以比起第一种方法可以节省应用程序apk的内存大小

3.WebView的进阶用法

1.前进返回按钮的实现

第一步,布局文件中添加按钮

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintLeft_toLeftOf="parent"
        android:layout_marginLeft="10dp"
        android:text="返回"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="10dp"/>
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_marginRight="10dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="10dp"
        android:text="前进"/>

<WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述
第二步,给button添加点击事件

       Button button=findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mWebView.goBack();//返回
            }
        });

        Button button2=findViewById(R.id.button2);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mWebView.goForward();//前进
            }
        });

在这里插入图片描述
运行
在这里插入图片描述
补充:

        mWebView.goBack();//跳到上个页面
        mWebView.goForward();//跳到下个页面
        mWebView.canGoBack();//是否可以跳到上一页(如果返回false,说明已经是第一页)
        mWebView.canGoForward();//是否可以跳到下一页(如果返回false,说明已经是最后一页)
        //以当前的index为起始点前进或者后退到历史记录中指定的steps
        //如果steps为负数则为后退,正数则为前进
         //  mWebView.goBackOrForward(3);
         //  mWebView.goBackOrForward(-3);
        mWebView.goBackOrForward(intsteps);
        //重新加载当前请求
        mWebView.reload();

2.清除缓存

 		//清除网页访问留下的缓存
        //由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
        mWebView.clearCache(true);
        //清除当前webview访问的历史记录
        //只会webview访问历史记录里的所有记录除了当前访问记录
        mWebView.clearHistory();
        //这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据
        mWebView.clearFormData();

3.网页自适应屏幕,缩放

子类1-WebSettings类

 		 WebSettings webSettings = mWebView.getSettings();
        //如果访问的页面中要与Javascript交互,则webview必须设置支持Javascript
        webSettings.setJavaScriptEnabled(true);//js开关默认不打开,网页中的所有js方法就无法执行,如果我们把这个方法设置为ture,网页中搞得js方法才可以执行 
        //设置自适应屏幕
        webSettings.setUseWideViewPort(true); //将图片调整到适合webview的大小
        webSettings.setLoadWithOverviewMode(false); // 缩放至屏幕的大小
        //缩放操作
        webSettings.setSupportZoom(false); //支持缩放,默认为true。是下面那个的前提。
        webSettings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false,则该WebView不可缩放
        webSettings.setDisplayZoomControls(false); //隐藏原生的缩放控件

在这里插入图片描述
补充:

		//其他细节操作
        //缓存模式如下:
        //LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据
        //LOAD_DEFAULT: (默认)根据cache-control决定是否从网络上取数据。
        //LOAD_NO_CACHE: 不使用缓存,只从网络获取数据.
        //LOAD_CACHE_ELSE_NETWORK,只要本地有,无论是否过期,或者no-cache,都使用缓存中的数据
        webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //webview缓存设置
        webSettings.setAllowFileAccess(true); //设置可以访问文件
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通过JS打开新窗口
        webSettings.setLoadsImagesAutomatically(true); //支持自动加载图片
        webSettings.setDefaultTextEncodingName("utf-8");//设置编码格式

4.WebView的子类

1.子类1-WebSettings类

2.子类2-WebViewClient类

该类作用:处理各种通知 & 请求事件

常见方法

  • onPageStarted(WebView view, String url, Bitmap favicon):WebView 开始加载页面时回调,一次Frame加载对应一次回调。

  • onPageFinished(WebView view, String url):WebView 完成加载页面时回调,一次Frame加载对应一次回 调。

  • onLoadResource(WebView view, String url):WebView 加载页面资源时会回调,每一个资源产生的一次网络加载,除非本地有当前 url 对应有缓存,否则就会加载。

  • shouldInterceptRequest(WebView view, String url):WebView 可以拦截某一次的 request 来返回我们自己加载的数据,这个方法在后面缓存会有很大作用。

  • shouldOverrideUrlLoading(WebView view, String url):是否在 WebView 内加载页面

  • onReceivedSslError(WebView view, SslErrorHandler handler, SslError error):WebView ssl
    访问证书出错,handler.cancel()取消加载,handler.proceed()对然错误也继续加载。

  • onReceivedError(WebView view, int errorCode, String description, String failingUrl):WebView 访问 url 出错

这里重点讲下这几种方法
1.onPageStarted和onPageFinished方法
–用于监控网页的开始和结束–可以适用于加载网页时的进度条

在这里插入图片描述
2.shouldOverrideUrlLoading

–所有加载的页面都会经过这个方法–可以用来拦截加载的网页
在这里插入图片描述
3.onReceivedError
–可以检测到加载异常的网络–从而可以返回一个我们自定义写好的错误界面,对用户体验会好很多
在这里插入图片描述
因为我的模拟器版本偏低,所以这里我用的旧版本写法
这里补充一下,新旧版本都兼容的写法:

    // 旧版本,会在新版本中也可能被调用,所以加上一个判断,防止重复显示
    @Override
    public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
        super.onReceivedError(view, errorCode, description, failingUrl);
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            return;
        }   
        // 在这里显示自定义错误页
    }
 
    // 新版本,只会在Android6及以上调用
    @TargetApi(Build.VERSION_CODES.M)
    @Override
    public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { 
        super.onReceivedError(view, request, error);
        if (request.isForMainFrame()){ // 或者: if(request.getUrl().toString() .equals(getUrl()))
            // 在这里显示自定义错误页
        }
    }

3.子类3-WebChromeClient类

该类作用:辅助 WebView 处理 Javascript 的对话框,网站图标,网站标题等

常用方法

  • onConsoleMessage(String message, int lineNumber,String sourceID):输出Web 端日志
  • onProgressChanged(WebView view, int newProgress):当前 WebView 加载网页进度。
  • onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result):处理 JS 中的 Prompt对话框
  • onJsAlert(WebView view, String url, String message, JsResult result): Js 中调用 alert() 函数,产生的对话框。
  • onReceivedTitle(WebView view, String title):接收web页面的 Title。
  • onReceivedIcon(WebView view, Bitmap icon):接收web页面的icon。

我们先添加一下新网页,
这里面有三个不同的弹框 -prompt,alert,confirm

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebView Study</title>
    <script>
function clickPrompt() {
prompt("prompt");
}
function clickAlert() {
alert("alert");
}
function clicConfirm() {
confirm("Confirm");
}
</script>
</head>
<body>
<button type="button" onclick="clickPrompt()">Prompt调用</button>
<button type="button" onclick="clickAlert()">Alert调用</button>
<button type="button" onclick="clicConfirm()">Confirm调用</button>
</body>
</html>

在这里插入图片描述

修改加载网页代码

mWebView.loadUrl("file:///android_asset/test.html");

在这里插入图片描述

运行
在这里插入图片描述

1.对js按钮的监听

在这里插入图片描述

  mWebView.setWebChromeClient(new WebChromeClient(){

            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                Log.i("Main","------onJsAlert");
                return super.onJsAlert(view, url, message, result);

            }

            @Override
            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
                Log.i("Main","------onJsConfirm");
                return super.onJsConfirm(view, url, message, result);
            }

            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
                Log.i("Main","------onJsPrompt");
                return super.onJsPrompt(view, url, message, defaultValue, result);
            }
        });

2.在js中自定义安卓弹框

在监听方法中加入代码

    AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this)
                        .setIcon(R.mipmap.ic_launcher)
                        .setTitle("title")
                        .setMessage("message")
                        .setPositiveButton("确定",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialogInterface, int i) {
                                        Toast.makeText(MainActivity.this, "确定按钮", Toast.LENGTH_LONG).show();
                                    }
                                }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                Toast.makeText(MainActivity.this, "关闭按钮", Toast.LENGTH_LONG).show();
                                dialogInterface.dismiss();
                            }
                        });
                builder.create().show();

                return true;//屏蔽默认的js弹框

在这里插入图片描述

ok 因为知识讲了挺多的,为了更好的消化,.本讲关于WebView的知识就先讲到这里啦,谢谢您的阅读,下一讲讲WebView的高级用法
Android入门第八讲02-WebView的高级用法(Android调用 JS 代码( loadUrl 方法,案例练习),JS调用 Android 代码,流行框架总结,跨平台技术)

猜你喜欢

转载自blog.csdn.net/qq_46526828/article/details/107808893
今日推荐