Android WebView 保持登录问题

Posted zhangxinyan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android WebView 保持登录问题相关的知识,希望对你有一定的参考价值。

最近有个需求是这样的:在应用中添加一个商城,商城的实现是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;
                }
            }
        });
    }
View Code

 

  • 在onPageFinished的时候,保存Cookie
技术分享图片
    private void saveCookies(String cookieString) {
        sp.edit().putString("cook", cookieString).apply();
    }
View Code

 

  • 在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());
        }
    }
View Code

 

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

 

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

以上是关于Android WebView 保持登录问题的主要内容,如果未能解决你的问题,请参考以下文章

Android 底部导航栏在 webview 中登录后显示

通过android webview自动登录网站的问题

如何将android webview保持在后台(使用位置)

Android WebView保存Cookie登录

保持 HttpUrlConnection 调用之间的会话(本机/Webview)

如何在 Android 中将 Button 放置在 WebView 的顶部