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

    • 1.WebView概述-加载网页
    • 2.WebView的基本用法
      • 第一步,添加权限
      • 第二步,添加控件
      • 第三步,获取网页
        • 1.加载远程网页
          • 1.一般网页
          • 2.特殊网页(会调用系统浏览器)
        • 2.加载本地网页
          • 1.assets目录
          • 2.data/data/包名目录
    • 3.WebView的进阶用法
      • 1.前进返回按钮的实现
      • 2.清除缓存
      • 3.网页自适应屏幕,缩放
        • 子类1-WebSettings类
    • 4.WebView的子类
      • 1.子类1-WebSettings类
      • 2.子类2-WebViewClient类
      • 3.子类3-WebChromeClient类
        • 1.对js按钮的监听
        • 2.在js中自定义安卓弹框

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" />

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 代码,流行框架总结,跨平台技术)

更多相关文章

  1. Android布局优化之ViewStub、include、merge使用与源码分析
  2. 什么?Android遇到瓶颈了?
  3. Android中ListView如何分页加载数据
  4. Android中利用“反射”动态加载R文件中的资源
  5. android 系统System UI Tuner大概讲解
  6. android volley解析与二次封装
  7. Android(安卓)webview加载https链接错误或无响应
  8. ListView分页加载数据
  9. Android加载Bitmap出现OutofMemoryError的原因(官方译文)

随机推荐

  1. 新建android工程 没有R.java文件
  2. 其他小知识点
  3. Android(安卓)透明度数值
  4. android sdk setup时呈现:Failed to fetc
  5. Android:实现类似RadioButton自动换行及
  6. 整理android环境离线安装搭建方法——支
  7. android学习笔记20--------------Relativ
  8. ProgressBar进度条
  9. Android编译报错
  10. Android(安卓)泛型使用