WebView的使用

背景

经过这么多的发展,目前的android应用开发模式已经有了很多的改变,除了有原来的原生应用开发模式,随着Html5等前端技术的进步,也催生了多种开
发模式。比如说目前非常火爆的native+web混合模式,其实就是在开发某个页面的时候,经常会更改,我们就可以使用网页的形式将页面的内容展示,应
用使用网页进行交互。本质上来说,还是内嵌了一个网页。
这种做法有什么优势呢?
1 开发方便,网页开发的成本要比原生开发应用的成本低
2 发布方便,如果我们的app上线后,我们有了新的业务需求,开发完成后,我们只能更新客户端或者使用热修复等技术,但是使用web的方式开
发的页面,直接将新的页面放上线上即可。
有优势的同时肯定也有劣势:
1 用户体验差,由于目前的前端技术暂时无法和原生的应用相比,所以开发出来的页面与原生的页面还是有差距
2 流量使用的多。
适合的场景:
1 信息展示的页面。Html+css提供了强大的排版能力,能够很方便的开发出需要的页面。
2 电商行业的活动页面。因为经常性的更改,网页的灵活性非常适合这种情况。

基本使用

布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="com.junx.x5webview.WebViewActivity">

    <WebView
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="300dp" android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp" android:layout_marginTop="8dp"
        app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintHorizontal_bias="0.352"
        app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>
代码:
public class MainActivity extends AppCompatActivity {

    private WebView wv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        setWebView();
    }

    private void initView() {
        wv = (WebView) findViewById(R.id.wv);
    }

    private void setWebView() {
        WebSettings webSettings = wv.getSettings();
        //设置WebView属性,能够执行Javascript脚本
        webSettings.setJavaScriptEnabled(true);
        //设置可以访问文件
        webSettings.setAllowFileAccess(true);
        //设置支持缩放
        webSettings.setBuiltInZoomControls(true);
        //加载需要显示的网页
        wv.loadUrl("http://www.baidu.com");
        //设置Web视图,不设置的话点击跳转网页则会打开默认浏览器
        wv.setWebViewClient(new WebViewClient());
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && wv.canGoBack()) {
            wv.goBack(); //goBack()表示返回WebView的上一页面
            return true;
        }
        finish();//结束退出程序
        return false;
    }
}
请记得添加网络权限

assets目录详解

创建assets目录:
在android视图下,选中整个module,右键>new>folder>assets folder

与res的区别:
在开发android应用的过程中,需要使用大量的资源文件,如果我们放置在res文件下,它会生成一个独立的id,而在assets文件夹下不会
如果我们需要获取assets的文件,我们可以使用getAssets().open打开一个文件。
加载assets目录下的文件的demo:

    private String getAssetsHtml(){
        StringBuilder builder=new StringBuilder();
        InputStream inputStream=null;
        InputStreamReader reader=null;
        BufferedReader bufferedReader=null;
        try {

            inputStream=getAssets().open("Image.html");
            reader=new InputStreamReader(inputStream);
            bufferedReader=new BufferedReader(reader);
            String cache ;
            while((cache = bufferedReader.readLine())!=null){
                builder.append(cache);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (inputStream!=null)
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            if (reader!=null)
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            if (bufferedReader!=null)
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
        return builder.toString();
    }

加载本地网页

使用电脑的浏览器,随便打开一个网页 ctrl+S,保存为html格式,复制到assets目录下
//通过file:///android_asset/文件名,加载网页 注意是asset而不是assets
wv.loadUrl("file:///android_asset/xxx.html");

加载动态网页

<html>
<head lang="en">
    <title></title>
    <h3>android,中文支持</h3>
    </style>
</head>
<body>
</body>
        <img class="image"   src="https://ss0.bdstatic.com
        /5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png">
</html>

将上述创建为一个字符串htmlString
加载字符串网页
        //如果网页中有中文的话可能会乱码
        wv.loadData(assetsHtml,"text/html,"UTF-8");
        //设置文字的编码格式,方式乱码
        wv.loadData(assetsHtml,"text/html;charset=UTF-8","UTF-8");

相对路径

将图片中的路径
        <img class="image"  src="https://ss0.bdstatic.com
        /5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png">
改为
        <img class="image"  src="
        /5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png">
改变后的路径是相对路径

那么,该如何加载相对路径的图片呢
//最后一个参数是历史url,如果为null当点击打开其他网页并返回时就为空白页面
wv.loadDataWithBaseURL("https://ss0.bdstatic.com",assetsHtml,"text/html;charset=UTF-8","UTF-8",null);

webview的事件监听

        wv.setWebViewClient(new WebViewClient(){
            //网页加载各种资源的回调,比如你的网页使用了各种图片和css与js文件
            public void onLoadResource(WebView view, String url) {
                super.onLoadResource(view, url);
            }
            //开始加载网页
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                showProgress();
            }
            //加载网页完成
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                hideProgress();
                Log.v("meee",getClass()+":\n"+"加载完成");
            }
            //加载页面出错时的回调 api6.0以上
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                hideProgress();
                //加载自己的错误页面
                //wv.loadUrl("file:///android_asset/error.html");
            }
            //5.1以下时错误的回调
            @Override
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                super.onReceivedError(view, errorCode, description, failingUrl);
                hideProgress();
            }
            //在这里处理网页内部的跳转
            //1.当没有设webclient时,跳转到默认浏览器
            //2.return true,url被拦截,webview也不处理跳转,需要自己进行loadurl
            //3.return false,webview自行处理,同super
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                return super.shouldOverrideUrlLoading(view, request);
            }
        });

WebView参数的设置

    private void setSetting(WebView webView){
        WebSettings settings = webView.getSettings();
        //是否允许使用file协议访问网页,默认true
        settings.setAllowFileAccess(true);
        //是否开始缩放功能
        settings.setBuiltInZoomControls(false);
        //设置页面字体的大小
        settings.setDefaultFontSize(30);
        //是否开启js支持
        settings.setJavaScriptEnabled(true);
        //是否开启两种数据库的支持
        /*html5支持数据库的功能,数据库有两种第一种官方的规范,DOM Storage,另外一种是第三方api ,Web SQL Database。我们先来讲讲这两种数
        据库存储方式。对于以前来说,一个Web应用要存储数据,大多会放置cookie中,但是cookie有一个限制,就是内容只能4K,且容易被篡改。所以
        在Html5内增加存储的概念,这个就是DOM Storage,DOM Storage 分为 sessionStorage 和 localStorage。 localStorage 对象和 sessionStorage
        对象使用方法基本相同,它们的区别在于作用的范围不同。sessionStorage 用来存储与页面相关的数据,它在页面关闭后无法使用。而
        localStorage 则持久存在,在页面关闭后也可以使用。*/
        settings.setDatabaseEnabled(true);
        settings.setDomStorageEnabled(true);
        //设置返回键时缓存的处理
        /*LOAD_DEFAULT(先从cache加载,没有且没有过期,再去网络加载),
        LOAD_CACHE_ELSE_NETWORK(先从cache加载,如果存在,不管有没有过期,都不会再去网络加载)
        , LOAD_NO_CACHE(不使用cache)
        ,LOAD_CACHE_ONLY(只使用cache)*/
        settings.setCacheMode(WebSettings.LOAD_DEFAULT);
    }

WebView的基本使用

a.加载网页
wv.load("url");
//加载本地网页
wv.loadUrl("file:///android_asset/my.html");//asset目录下,my.html
asset放在main目录下
//调用js  
wv.getSettings().setJavaScriptEnabled(true);    //开启js
webView.loadUrl("javascript:go()"); //调用js中的go();
//直接调用html代码
String data="<html><head></head><body>你好啊</body></html>";
wv.loadDataWithBaseURL(null,data,null,"utf-8",null);
//F5
wv.reload();
//后退
wv.canGoBack();
wv.goBack();

WebViewClient //WebView的辅助类,主要用于对WebView的监听

- onLoadResource:加载网页中的各种资源(比如:图片、css)时的回调
- onPageStarted:网页开始加载时的回调
- onPageFinished:网页结束加载时的回调
- onReceiverdError:网页加载失败时的回调
- shouldOverrideUrlLoading(WebView view, String url)//处理网页内部的跳转,比如请求www.bbbb.com,网页会请求到其他的页面,此时通过该方法就能进行处理。url的是过时的方法,但主要使用的也是它;return true离开页面并处理自身的url,false只做监听不做跳转
- shouldInterceptRequest(WebView view, String url/*资源的url*/):拦截网页中的请求。//return 就是返回的数据.思路:对url进行判断,对需要拦截的请求返回自定义的WebResourceResponse

WebChromeClient //主要用与页面交互

  //js 的confirm
  function display_confirm()
  {
  var r=confirm("Press a button")
  if (r==true)
    {
    document.write("You pressed OK!")
    }
  else
    {
    document.write("You pressed Cancel!")
    }
  }
  //js 的prompt
    function display_prompt()
  {
  var name=prompt("请输入你的名字","老司机")
  if (name!=null && name!="")
    {
    document.write("Hello " + name + "!")
    }
  }
  //js 的页面跳转
    function go()
  {
    window.location = "api://userId";
  }
  //js java调用
   function jsCallJava()
  {
    window.demo.startPage();
  }

wv.setWebChromeClient(new WebChromeClient(){
    //js中对alert方法进行监听
    @Override
    public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
        uu(message);//log对话框中的信息
        return super.onJsAlert(view, url, message, result);
    }
    //确认框监听
    @Override
    public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
        return super.onJsConfirm(view, url, message, result);
    }
    //prompt :进阶的输入框  
    @Override
    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
        return super.onJsPrompt(view, url, message, defaultValue, result);
    }

    @Override
    public void onReceivedIcon(WebView view, Bitmap icon) {
        super.onReceivedIcon(view, icon);
    }

    @Override
    public void onReceivedTitle(WebView view, String title) {
        super.onReceivedTitle(view, title);
    }

    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        super.onProgressChanged(view, newProgress);
    }
});

WebSetting

//获取Setting的方法
wv.getSettings();
//设置是否开启网页的JS
setting.setJavaScriptEnabled(boolean flag):设置是否执行页面中的js方法
//是否需要是否允许访问file文件
setting.setAllowFileAccess(boolean allow);常用于访问assets和raw文件夹下面的网页
//设置是否使用webView自带的缩放功能
setting.setBuiltInZoomControls(boolean enabled);
//设置页面的文字大小
setting.setDefaultFontSize(int size)
//
setting.setCacheMode(int);
    LOAD_DEFAULT(只有缓存不存在或者已经过期时才会从网络加载)
    LOAD_CACHE_ELSE_NETWORK(不论缓存是否过期,只有缓存不存在时才会从网络加载)
    LOAD_CACHE_ONLY
- setBuiltInZoomControls(boolean enabled):

Java页面交互

//通过控制跳转的方式来实现java页面交互
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    if (url.startsWith("http:")) {
    } else if (url.startsWith("data")) {
        //todo  开启一个新的页面
    }
    return true;//true不能加载网页
}

//在html中调用java方法
@JavascriptInterface
test();//在某一个类中具有的方法,需要添加注解@JavascriptInterface
//在java中关联html
wv.addJavaScriptInterface(MainActivity.this/*方法的实例*/,"instance"/*该类的昵称*/);instance
//在html中添加方法 window.传入的类的昵称.方法();
  function callJava()
  {
    window.instance.toast();
  }

List 并没有实现seriable,所以

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值