美文网首页android收集Android知识Android开发
说说WebView那些事(header,cookie,注入js

说说WebView那些事(header,cookie,注入js

作者: 文淑 | 来源:发表于2017-02-24 09:10 被阅读1927次

    前言

    昨天路过公司外面花园时候,不知觉腊梅已经开花了,才发觉春天来了。来城市生活这几年,完全忘记了时令的交替,只知道冷了加衣服,热了脱衣服。好久没感受到春天的气息了,内心泛起一丝惆怅。城市的生活总是那么匆忙,多了一分烦躁,少了一分宁静。

    那金黄色的油菜花,粉色的桃花,白色的李子花樱花 . . . 儿时 . . .

    WebView简介

    纯原生app开发,时间成本太高,现在市面上已经很多混合式开发app。那么什么是混合式?指的是在我们的页面中嵌入html网页。Android当中给我们提供了WebView实现这一功能。

    有关WebView的一些常见方法,我这里就不再讲解,网上这部分资源太多。接着我们来看看以下几个案列。

    参考文献:

    WebView详解与简单实现Android与H5互调

    案例一header

    直接上需求效果图:

    web

    需求:WebView添加headerh5读取头部,并且隐藏底部菜单栏。

    需要添加的header数据:ECR-APP:android

    我们平时大多数情况使用的是loadUrl(String url)加载方法,下面我们来看另一个loadUrl构造方法。

    loadUrl(String url, Map<String, String> additionalHttpHeaders)
    

    参数additionalHttpHeaders字面上的意思是:额外的http头部信息。这个方法是Android 2.2 (也就是API 8),WebView新增加了一个接口方法,就是为了便于我们加载网页同时又可以发送HTTP头信息的。

    看看具体的使用:

        HashMap<String, String> header = new HashMap<>();
        header.put("ECR-APP", "android");
        
        mWebView.loadUrl("http://m.test.366ec.net/Default2c.aspx",header);
    

    马上运行效验一下:

    web

    网页上底部的菜单已经去掉了。

    案例二cookie

    cookie用于记录用户登录信息,用户下次进入需要登录的界面不再需要重复登录。

    先看看需求:

    web

    会一直出现登录界面。那么怎么解决多次登录问题?WebView会将加载的url通过http请求传输到服务器。那么Cookie信息会通过header传递过去。

    设置cookie代码如下:

        private void syncCookieToWebView(String url, List<String> cookies) {
            CookieSyncManager.createInstance(this);
            CookieManager cm = CookieManager.getInstance();
            cm.setAcceptCookie(true);
            if (cookies != null) {
                for (String cookie : cookies) {
                    cm.setCookie(url, cookie);//注意端口号和域名,这种方式可以同步所有cookie,包括sessionid
                }
            }
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
                CookieManager.getInstance().flush();
            } else {
                CookieSyncManager.getInstance().sync();
            }
        }
    

    以下是调用代码:

        List<String> cookies = new ArrayList<>();
        //键值对类型  用等号("=")连接    具体根据后台给定
        cookies.add("StoreManagerTicket=" + "加密token");//根据后台协商而定
        syncCookieToWebView("加载的地址", cookies);
    

    CookieManager会将这个Cookie存入该应用程序/data/data/databases/目录下的webviewCookiesChromium.db数据库的cookies表中。打开网页,WebView从数据库中读取该cookie值,放到http请求的头部,传递到服务器。

    运行一下,看看还会出现多次登录的问题吗?

    web

    跳转正常,没有出现多次登录的问题。

    案例三注入js

    不知道你在项目中遇到这样的场景没有?手机端与h5交互,提供数据支持。如调本地相机,获取到的图片上传到网页;调用定位返回地址给网页;调用二维码扫描界面返回扫描结果等等。

    如下,有这样一个场景,网页上有【扫描】图标,点击打开手机扫描界面,扫描成功后上传扫描结果。那么在手机端一般会有如下方法:

    JsOpenScanFunction(String callbackFunction)
    

    参数callbackFunction表示扫描成功后webview.load调用的方法并且只有一个参数(扫描结果)。

    一般前端h5会这样进行调用Android手机端打开二维码的方法:

    //callback回调方法
    window.JsInterface.JsOpenScanFunction(callback)
    

    ios端会这样调用:

    window.webkit.messageHandlers.JsOpenScanFunction.postMessage(callback)
    

    在h5端会分步处理,无疑会增加开发人员的工作量,试想一下,如果交互的地方很多,那么h5端开发人员作何感想?而且后期的维护也是一件非常繁琐的事情,就没有更好的方案吗?

    如果h5端可以像调用本地方法那样简单调用手机端方法,那不是非常fashion

    那么就需要分别在Android端和ios端分布注入js代码,方便h5端调用。

    注入的方式如下:

            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            if (mIsAddJsCode) {//默认true
                mIsAddJsCode = false;
                mWebView.loadUrl("javascript:" + "function JsOpenScanFunction(s) {\n    window.JsInterface.JsOpenScanFunction(s);\n}");
            }
        }
    

    onPageStarted方法下注入js方法:

    function JsOpenScanFunction(s) {
        window.JsInterface.JsOpenScanFunction(s);
    }
    

    这样h5只需要调用JsOpenScanFunction(s)方法就可以实现不同平台调用二维码扫描的功能。从此妈妈在已不担心多端调用的问题了。

    注意:JsOpenScanFunction(s) 方法,需要前端和移动端事先约定。

    文章就讲到这里了,如果有什么不对的地方还请指出,有什么好的意见请给我留言,我会在第一时间给予回复。

    楼主不才,新建了QQ群讨论技术,欢迎大家的加入 478720016

    我非常喜欢【平凡世界】里的一句话。我是一个平凡的人,但一个平凡的人,也可以过得不平凡。

    相关文章

      网友评论

      本文标题: 说说WebView那些事(header,cookie,注入js

      本文链接:https://www.haomeiwen.com/subject/pmgiwttx.html