最近有个需求是这样的:在应用中添加一个商城,商城的实现是H5(包括登录)。需要将这个H5嵌到原生应用中,并在原生代码中添加支付功能。

接到这个需求的时候,想这不是很简单么,用WebView加载这个页面,通过Js回调原生方法,然后调用第三方支付,完工。

然而到实际开发的时候,问题就出现了。

首先的问题是:

1.在商城中,点击了一个商品,然后确认购买。

2.此时没有登录,会跳到登录界面。

3.没关系,那就登录一下。

4.登录完后,再次点击这个商品,然后去购买。

5.然后问题就出现了,前面不是登录过了吗?怎么还跳到登录界面了?

分析:

一开始以为是H5写的不对,然而我用浏览器打开的时候,是好的,跳转也正常,所以,还是WebView设置的有问题。

一通百度之后,初步断定是Cookie同步的问题,但是网络这一块一直不太懂,当下也没时间细细研究,所以就照着百度所得之后一步步尝试。下面是我的解决方法。

解决方法:

  • 初始化WebView
private void initWebView() {
        WebSettings webSettings = webview.getSettings();
        // 设置编码
        webSettings.setDefaultTextEncodingName("utf-8");
        webSettings.setTextZoom(100);
        //自适应屏幕
        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        webSettings.setLoadWithOverviewMode(true);

        // 支持js
        webSettings.setJavaScriptEnabled(true);

        // 设置本地调用对象及其接口
        jsBridge = new JavaScriptBridge(getActivity(), webview);
        webview.addJavascriptInterface(jsBridge, "Native");

        CookieManager mCookieManager = CookieManager.getInstance();
        mCookieManager.setAcceptCookie(true);
        mCookieManager.setAcceptThirdPartyCookies(webview, true);
        webview.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                // //获取webview里面的cookie信息
                CookieManager cookieManager = CookieManager.getInstance();
                cookieManager.setAcceptCookie(true);
                String cookieStr = cookieManager.getCookie(url);
                saveCookies(cookieStr);
                progressBar.setVisibility(View.GONE);
            }

            @Override
            public void onReceivedError(WebView view, int errorCode, String description, final String failingUrl) {
            }

            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (url.startsWith("http") || url.startsWith("https")) {
                    if (url.startsWith("http://shop.yinm")) { //这个WebView是通用的,只对这个商城的链接做Cookie操作。
                        syncCookie(getContext(), url);
                    }
                    view.loadUrl(url);
                    return false;
                } else {
                    //其他的URL则会开启一个Acitity然后去调用原生APP
                    try {
                        Intent in = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                        in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_SINGLE_TOP);
                        startActivity(in);
                        view.stopLoading();
                    }catch (Exception e) {
                        e.printStackTrace();
                    }
                    return true;
                }
            }
        });
    }
  • 在onPageFinished的时候,保存Cookie
    private void saveCookies(String cookieString) {
        sp.edit().putString("cook", cookieString).apply();
    }
  • 在loadUrl(url)前,同步Cookie
    private void syncCookie(Context context, String url){
        try{
            CookieSyncManager.createInstance(context);

            CookieManager cookieManager = CookieManager.getInstance();
            cookieManager.setAcceptCookie(true);
            cookieManager.removeSessionCookie();// 移除

            //log
            String oldCookie = cookieManager.getCookie(url);
            if(oldCookie != null){
                android.util.Log.i("zxy", "getCookie oldCookie    " + oldCookie);
            }

            String cookie = sp.getString("cook", "");
            String[] cookies = cookie.split(";");
            if (!TextUtils.isEmpty(cookie)) {
                for (String cook : cookies) {
                    cookieManager.setCookie(url, cook.trim()); //一定要一个一个set, 如果是拼接的话,设置不成功。
                }
            }

            //最后一定要调用
            CookieSyncManager.getInstance().sync();

            //log
            String newCookie = cookieManager.getCookie(url);
            if(newCookie != null){
                android.util.Log.i("zxy", "getCookie newCookie    " + newCookie);
            }
        }catch(Exception e){
            android.util.Log.i("zxy", "getCookie failed" + e.toString());
        }
    }

这样,就可以实现Cookie同步了。

(网路这一块,找个时间要好好补补)

Android WebView 保持登录问题的更多相关文章

  1. Android WebView 302斗争之旅

    一.背景 越来越多的业务接入,项目内多多少少会出现几个H5页面,只是单纯的提供WebView容器接入H5页面根本满足不了需求,他们需要登录态,需要制定协议控制Native的导航栏,或者需要JsBrid ...

  2. Android WebView 开发详解(二)

    转载请注明出处  http://blog.csdn.net/typename/article/details/39495409 powered by miechal zhao   概览: Androi ...

  3. Android WebView存在跨域访问漏洞(CNVD-2017-36682)介绍及解决

    Android WebView存在跨域访问漏洞(CNVD-2017-36682).攻击者利用该漏洞,可远程获取用户隐私数据(包括手机应用数据.照片.文档等敏感信息),还可窃取用户登录凭证,在受害者毫无 ...

  4. webview之如何设计一个优雅健壮的Android WebView?(下)(转)

    转载:https://iluhcm.com/2018/02/27/design-an-elegant-and-powerful-android-webview-part-two/ (这篇文章写得有点晚 ...

  5. webview之如何设计一个优雅健壮的Android WebView?(上)(转)

    转接:https://iluhcm.com/2017/12/10/design-an-elegant-and-powerful-android-webview-part-one/ 前言 Android ...

  6. Android WebView 详解

    相关API 相关类介绍 WebResourceRequest 添加于API21,封装了一个Web资源的请求信息,包含:请求地址,请求方法,请求头,是否主框架,是否用户点击,是否重定向 WebResou ...

  7. 如何设计一个优雅健壮的Android WebView?(下)

    转:如何设计一个优雅健壮的Android WebView?(下) 前言 在上文<如何设计一个优雅健壮的Android WebView?(上)>中,笔者分析了国内WebView的现状,以及在 ...

  8. 如何设计一个优雅健壮的Android WebView?(上)

    转:如何设计一个优雅健壮的Android WebView?(上) 前言 Android应用层的开发有几大模块,其中WebView是最重要的模块之一.网上能够搜索到的WebView资料可谓寥寥,Gith ...

  9. android WebView详细使用方法(转)

    1.最全面的Android Webview详解 2.最全面总结 Android WebView与 JS 的交互方式 3.你不知道的 Android WebView 使用漏洞 如果想保证登录状态,就插入 ...

随机推荐

  1. ASP.NET MVC 之自定义HtmlHelper

    前言 HtmlHelper方法为我们提供很多html标签,只需在页面调用就行了,但是微软并没有把所有的html标签都对应有了扩展方法,需要我们重新自定义HtmlHelper,来满足我们需要. 方法 如 ...

  2. 爬虫的入门以及scrapy

    一.简介 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟 ...

  3. 最先进的开源游戏引擎KlayGE 4.3发布

    转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2536 经过KlayGE团队半年来的努力,今天KlayGE 4.3正式发布了!在这个版本的开发 ...

  4. BIEE 11g 安装

    1.安装oracle 创建字符集为AL32UTF8的实力MERIT  sys密码merit 创建biee用户 create tablespace biee datafile 'D:\ORADATA\M ...

  5. NPAIRS框架的理解

    <The NPAIRS Computational Statistics Framework for Data Analysis in Neuroimaging> Strother. pe ...

  6. PHP 函数:intval()

    intval   变量转成整数类型. 语法: int intval(mixed var, int [base]); 返回值: 整数 函数种类: PHP 系统功能 内容说明:本函数可将变量转成整数类型. ...

  7. SystemTimeToFileTime、FileTimeToLocalFileTime、LocalFileTimeToFileTime三函数的跨平台实现

    // test.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdlib.h>   #include & ...

  8. YesFinder - 网页文件管理系统 V2.0

    2.0版增加了模态框并重写了右键菜单插件.界面改为全中文.使用方式更加灵活. 同时,文件及目录改名更方便,直接双击名称就可改名. 这是DEMO的效果图. 1.功能上的主要改进是可以双击改文件/目录名称 ...

  9. 史上最简单的Hibernate入门简单介绍

    事实上Hibernate本身是个独立的框架,它不须要不论什么web server或application server的支持.然而,大多数的Hibernate入门介绍都加入了非常多非Hibernate ...

  10. Linux svnserver存储路径和文件的详细解释

    svn有两种存储方式:BDB和FSFS,眼下用的最多的是FSFS方式,这样的方式的话.通常是存储在\db\revs目录下,里面有一堆以版本命名的文件.如:0.1.2.3.4......,那个就是了 比 ...