项目中如果用到了 WebView,那就免不了跟 Cookie 打交道。

比如,你时常需要判断用户的登录状态,如果用户未登录,那就必须限制部分功能的使用。

那么原生 Android 该如何获取 WebView 中的 Cookie 呢?

我们可以定制一个 WebViewClient 并重写内部的相关方法来实现,并不建议使用匿名类的方式。新建一个类 MyWebViewClient 继承自 WebViewClient,然后重写其 onPageFinished(WebView, String) 方法:

public class MyWebViewClient extends WebViewClient {
    String cookieTag = null;
    String cookieTel = null;
    @Override
    public void onPageFinished(WebView view, String url) {
        super.onPageFinished(view, url);
        CookieManager cookieManager = CookieManager.getInstance();
        String cookieStr = cookieManager.getCookie(url);
        try {
            cookieTag = cookieStr.substring(0, 8);     // 确定前缀是不是 phoneNum
            if (cookieTag.equals("phoneNum")) {
                cookieTel = cookieStr.substring(9, 20);    // phoneNum 后面的电话号码
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public String getCookieTag() {
        return cookieTag;
    }
    public String getCookieTel() {
        return cookieTel;
    }
}

使用 CookieManagergetCookie() 方法来获取存储的 Cookie,这里判断 Cookie 中的前缀是否为 phoneNum,如果是的话证明已经登录,并截取后面 11 位数字为用户的手机号码,然后通过 Getter 来提供传值方法。

然后在 WebView 中配置这个自定义的 WebViewClient

MyWebViewClient myWebViewClient = new MyWebViewClient();
webView.setWebViewClient(myWebViewClient);

接着就可以通过相关的 Getter 方法来获取传值:

String tel = myWebViewClient.getCookieTel();

于是获取 Cookie 的方法就完成了。

有了 Cookie,当用户退出登录时,我们也需要清除 Cookie

logOutBtn.setOnClickListener(v -> {
    CookieSyncManager.createInstance(this);
    CookieSyncManager.getInstance().startSync();
    CookieManager.getInstance().removeSessionCookie();
    CookieManager.getInstance().removeAllCookie();
    CookieSyncManager.getInstance().sync();
    webView.clearCache(true);
    webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
    webView.loadUrl(loginUrl);          // 重新加载登录页面
    Intent intent = getIntent();
    finish();
    startActivity(intent);
});

Android 为我们提供了很多与清除 Cookie 相关的操作,我基本都写上去了,你会发现我在下面销毁了当前 Activity 并重新启动,原因是上面清除的是本地的 Cookie,但有些逻辑我们已经从 Cookie 中获取了值并存储在全局变量中,使某些登录后才能使用的功能即使在清除 Cookie 后依然可以使用,所以销毁当前 Activity 可以把依附该 Activity 上的变量或引用随着 Activity 的生命周期而消亡。

当然也可以通过其他的逻辑避免这个问题,不过我觉得会复杂很多,不如这个方法用得方便。