简述 Android和H5交互
发布日期:2021-05-06 20:21:08 浏览次数:31 分类:精选文章

本文共 7221 字,大约阅读时间需要 24 分钟。

  1. 1 — WebView基本配置
  2. 2 —WebView和H5的交互
  3. 3 — WebView错误页面处理
  4. 4 —WebView中的Cookie操作
  5. 5 —WebView漏洞
  6. 6 —WebView内存泄漏问题

1WebView基本配置

布局设置 
这里写图片描述

代码设置

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29

初如化控件

//初始化控件        Button btn1 = (Button) findViewById(R.id.btn1);        btn1.setOnClickListener(this);        Button btn2 = (Button) findViewById(R.id.btn2);        btn2.setOnClickListener(this);        wv = (WebView) findViewById(R.id.wv);        //获取webSettings        WebSettings settings = wv.getSettings();        //让webView支持JS        settings.setJavaScriptEnabled(true);        //加载百度网页        wv.loadUrl("http://www.baidu.com/");        //这个时候就能显示百度页面了    1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17

2 WebView和H5的交互

这里写图片描述 
我们自己写一个H5页面 放在assets目录下 
注意 : 如果html文件存于assets:则加前缀:file:///android_asset/ 
如果在Sdcard直接使用file:///sdcard/ or file:/sdcard也可以

  //加载本地assets目录下的静态网页    wv.loadUrl("file:///android_asset/123.html");    //第一个参数把自身传给js 第二个参数是this的一个名字    //这个方法用于让H5调用android方法    wv.addJavascriptInterface(this, "android");    1   2   3   4   5

Android调用JS方法

这里写图片描述

//这个是button的点击事件 @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btn1:                //参数 “javascript:”  +  js方法名                wv.loadUrl("javascript:message()");                break;            case R.id.btn2:                //在android调用js有参的函数的时候参数要加单引号                wv.loadUrl("javascript:message2('" + name + "')");                break;        }    }    1   2   3   4   5   6   7   8   9   10   11   12   13   14   15

JS调用Android方法 
这里写图片描述

//下面的两个方法是让网页来调的    //这个注解必须加 因为 兼容问题    @JavascriptInterface    public void setMessage() {        Toast.makeText(this, "我弹", Toast.LENGTH_SHORT).show();    }    @JavascriptInterface    public void setMessage(String name) {        Toast.makeText(this, "我弹弹" + name, Toast.LENGTH_SHORT).show();    }    1   2   3   4   5   6   7   8   9   10   11

H5代码,如果H5看不懂请自行百度

    
点我试试百度
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41

第二种交互方式 而是采用scheme + cookie的方式

--1、Java 调用 js里面的函数、效率低、估计要200ms左右而js去调Java的方法、速度很快、50ms左右、所以尽量用js调用Java方法--2、Java 调用 js 的函数、没有返回值、调用了就控制不到了--3、Js 调用 Java 的方法、返回值如果是字符串、你会发现这个字符串是 native 的、转成 locale 的才能正常使用 --4、网页中尽量不要使用jQuery、执行起来需要5-6秒、最好使用原生的js写业务脚本、以提升加载速度、改善用户体验 --5、Android4.2以下的系统存在着webview的js对象注入漏洞…Android API 16 没有正确限制使用webview.addJavaScripteInterface方法,远程攻击者 使用JavaReflectionAPI利用执行任意java对象的方法

scheme设置:对于要启动的Activity

//这一章不详细讲解scheme的使用
1 2 3 4 5 6 7 8 9

看一下原来的H5代码

点我试试    1

注意:

//Url地址  aa://atguigu/path 下面的是Activity清单文件的配置上下对比其实和我们的URL地址是一样的aa 是 schemehost 是主机名称path 是路径当然还可以配置端口和加参数aa://atguigu:8080/path?id = 10通过activity配置那么就可以跳转到相应的界面里,如果activity只配置scheme = aa那么只要是aa的Url都是适配的    1   2   3   4   5   6   7   8   9   10   11   12
wv.setWebViewClient(new WebViewClient() {//当页面开始加载的时候调用此方法            @Override            public void onPageStarted(WebView view, String url, Bitmap favicon) {                super.onPageStarted(view, url, favicon);              //通过对URl的解析来决定调转到哪个页面              //这边只是简单做一些判断当前是否是Scheme跳转                if (url.contains("aa")) {                    Intent intent = new Intent(Intent.ACTION_VIEW,                            Uri.parse(url));                    startActivity(intent);                }            }    1   2   3   4   5   6   7   8   9   10   11   12   13   14

3WebView错误页面处理

场景 : 加载webview错误时加载网页的错误页面,体验不好,速度慢,这个时候就需要我们自行处理错误页面

第一步 先做一个错误的H5页面放在本地,或者加载Activity都可以 
这里写图片描述

wv.setWebViewClient(new WebViewClient() {     @Override            public void onReceivedError(WebView view, int errorCode,                                        String description, String failingUrl) {                super.onReceivedError(view, errorCode, description, failingUrl);                Log.i(TAG, "onReceivedError: " + errorCode + "  " + description);                //判断错误类型                if (errorCode == ERROR_UNSUPPORTED_SCHEME) {                    Log.i(TAG, "onReceivedError: " + "true");                    //停止加载错误页面,否则会显示原来H5加载的错误页面                    //再跳到现在的错误页面,体验不好,当然也可以做其它操作                    view.stopLoading();                    view.loadUrl("file:///android_asset/error.html");                }            }}    1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18

4WebView中的Cookie操作

关于Cookie的介绍在这不再详说

场景:webView需要保存从网页中获取到的Cookie 在涉及到账户体系的产品中,包含了一种登录状态的传递。比如,在Native(原生)界面的登录操作,进入到Web界面时,涉及到账户信息时,需要将登录状态传递到Web里面,避免用户二次登录。这里就涉及到WebView加载网页时的Cookie操作了。通常我们在登录时获取到用户的Cookie信息,然后将其保存到sdcard的WebView缓存文件当中,这样在加载网页时,WebView会自动将当前url的本地Cookie信息放在http请求的request中,传递给服务器

获取cookie

//加载百度网站wv.loadUrl("http://www.baidu.com");wv.setWebViewClient(new WebViewClient() {    @Override            public void onPageStarted(WebView view, String url, Bitmap favicon) {                super.onPageStarted(view, url, favicon);               CookieManager instance = CookieManager.getInstance();               //这样就可以获取到Cookie了               String cookie = instance.getCookie(url);               Log.i(TAG, "onPageStarted: "+cookie);            }}    1   2   3   4   5   6   7   8   9   10   11   12   13   14

设置cookie

//创建CookieSyncManager 参数是上下文        CookieSyncManager.createInstance(context);        //得到CookieManager        CookieManager cookieManager = CookieManager.getInstance();        //得到向URL中添加的Cookie的值        String cookieString;//获取方法不再详述,以项目要求而定        //使用cookieManager..setCookie()向URL中添加Cookie        cookieManager.setCookie(url, cookieString);        CookieSyncManager.getInstance().sync();    1   2   3   4   5   6   7   8   9

5WebView漏洞和内存泄漏

/* 

* ① Android API 16 没有正确限制使用webview.addJavaScripteInterface方法,远程攻击者使用 JavaReflectionAPI利用执行任意java对象的方法 

* ② webview在布局文件中的使用:webView写在其它容器中时 (先销毁webview再销毁activity)因为 webview是独立进程,最好创建个viewGroup用来放置webview,Activity创建时add进来,在Activity停止时remove掉 

* ③使用 jsbridge(详情看下面) 

* ④ 在此方法的操作放到后者使用webviewClient.onPageFinished->WebChromeClient.onProgressChanged 

* ⑤ 后台耗电问题 :activity不可见时要停用webview 

* ⑥ webview硬件加速导致页面渲染问题-白屏展示(关闭硬件加速) 

* ⑦动态添加webview,对传入webview中使用的context使用弱引用,动态添加webview意思在布局 
* */

JSBridge

什么是JsBridge

WebViewJavascriptBridge是移动UIView和Html交互通信的桥梁,就是实现java和js的互相调用的桥梁。替代了WebView的自带的JavascriptInterface的接口,使得开发者更方便的让js和native灵活交互,使我们的开发更加灵活和安全。

JSBridge的优点

Android API 4.4以前,谷歌的webview存在安全漏洞,网站可以通过js注入就可以随便拿到客户端的重要信息,甚至轻而易举的调用本地代码进行流氓行为,谷歌后来发现有此漏洞后,在API 4.4以后增加了防御措施,如果用js调用本地代码,开发者必须在代码申明JavascriptInterface, 列如在4.0之前我们要使得webView加载js只需如下代码:mWebView.addJavascriptInterface(new JsToJava(), "myjsfunction");4.4之后使用时需要在调用Java方法加入@JavascriptInterface注解,如果代码无此申明,那么也就无法使得js生效,也就是说这样就可以避免恶意网页利用js对客户端的进行窃取和攻击。 但是即使这样,我们很多时候需要在js调用本地java代码的时候,要做一些判断和限制,或者有的场景也会做些过滤或者对用户友好提示,甚至更复杂的Hybrid模式下,需要js和native之间进行交互通讯,拍照上传,因此原生的JavascriptInterface 就比较维护了,特此有了基于JavascriptInterface 封装的WebViewJavascriptBridge框架。

JsBridge: 

上一篇:Java 对象序列化
下一篇:深入解析OkHttp3

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2025年04月11日 17时28分29秒