Andorid下的webview的CookieManager全解析

#Android下webview的CookieManager详解

CookieManager介绍

  • java.net.CookieManager
    • java.net.CookieManager供java工程使用的(略)
  • android.webkit.CookieManager
    • android.webkit.CookieManager包下提供了供andorid系统使用的一个cookie管理的类
      • Manages the cookies used by an application’s WebView instances.
        • Cookies are manipulated according to RFC2109.

          使用场景

  • Android APP应用的某些功能, 需要调用内嵌的WebView去加载某个URL使用. 但用户在手机APP已经成功登录过了. 这时, 如果在内置浏览器去打开网页还需要用户再输入登录一次, 似乎显得不够人性化. 又或者, 用户在内置浏览器(WebView) 访问过一些页面, 想把这些有用的 Cookies 信息保存在本地. 因此, 我们会想, 要是能管理APP上浏览器(WebView) 在该站点URL的 Cookies, 使后台识别为已登录, 棒棒哒~

使用步骤

  • 1、客户端通过以下代码设置cookie

    1
    2
    CookieManager cookieManager = CookieManager.getInstance(); //获取单例对象
    cookieManager.setCookie(url, "uid=test_value"); //同步方法,给url设置cookie字段,key为uid,value为test_value
  • 2、CookieManager会将这个Cookie存入该应用程序/data/data/databases/目录下的webviewCookiesChromium.db数据库的cookies表中

  • 3、打开网页,WebView从数据库中读取该cookie值,放到http请求的头部,传递到服务器

  • 4、客户端可以在某些时刻清除该应用程序用到的所有cookies

    1
    2
    CookieManager cookieManager = CookieManager.getInstance(); //获取单例对象
    cookieManager.removeAllCookie();//清除所有的cookie

天坑所在

  • removeAllCookie()与removeSessionCookies()竟然是异步的删除cookie的方法,但是却没有回调。所以会出现一种您觉得你删除成功了,其实并没有删除成功的情况,那你再次登录可能会存在cookie同步不合预期的情况产生。

    API解析

  • 以下来解析源码,read the funk source code:
    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    /**
    * Gets the singleton CookieManager instance.
    *
    * @return the singleton CookieManager instance
    */
    public static synchronized CookieManager getInstance() { //获取单例对象
    return WebViewFactory.getProvider().getCookieManager();
    }
    /**
    * Sets whether the application's {@link WebView} instances should send and
    * accept cookies.
    * By default this is set to true and the WebView accepts cookies.
    * <p>
    * When this is true
    * {@link CookieManager#setAcceptThirdPartyCookies setAcceptThirdPartyCookies} and
    * {@link CookieManager#setAcceptFileSchemeCookies setAcceptFileSchemeCookies}
    * can be used to control the policy for those specific types of cookie.
    *
    * @param accept whether {@link WebView} instances should send and accept
    * cookies
    */
    public abstract void setAcceptCookie(boolean accept); //设置是否接受cookie,默认是true
    /**
    * Gets whether the application's {@link WebView} instances send and accept
    * cookies.
    *
    * @return true if {@link WebView} instances send and accept cookies
    */
    public abstract boolean acceptCookie(); //获取webview是否接受cookie
    /**
    * Sets whether the {@link WebView} should allow third party cookies to be set.
    * Allowing third party cookies is a per WebView policy and can be set
    * differently on different WebView instances.
    * <p>
    * Apps that target {@link android.os.Build.VERSION_CODES#KITKAT} or below
    * default to allowing third party cookies. Apps targeting
    * {@link android.os.Build.VERSION_CODES#LOLLIPOP} or later default to disallowing
    * third party cookies.
    *
    * @param webview the {@link WebView} instance to set the cookie policy on
    * @param accept whether the {@link WebView} instance should accept
    * third party cookies
    */
    public abstract void setAcceptThirdPartyCookies(WebView webview, boolean accept);// 设置跨域cookie读取,当Build.Version小于kitkat时候,默认值是true,之后的为false
    /**
    * Gets whether the {@link WebView} should allow third party cookies to be set.
    *
    * @param webview the {@link WebView} instance to get the cookie policy for
    * @return true if the {@link WebView} accepts third party cookies
    */
    public abstract boolean acceptThirdPartyCookies(WebView webview); //获取是否设置了跨域cookie读取
    /**
    * Sets a cookie for the given URL. Any existing cookie with the same host,
    * path and name will be replaced with the new cookie. The cookie being set
    * will be ignored if it is expired.
    *
    * @param url the URL for which the cookie is to be set
    * @param value the cookie as a string, using the format of the 'Set-Cookie'
    * HTTP response header
    */
    public abstract void setCookie(String url, String value); //根据URL设置cookie字段
    /**
    * Sets a cookie for the given URL. Any existing cookie with the same host,
    * path and name will be replaced with the new cookie. The cookie being set
    * will be ignored if it is expired.
    * <p>
    * This method is asynchronous.
    * If a {@link ValueCallback} is provided,
    * {@link ValueCallback#onReceiveValue(T) onReceiveValue()} will be called on the current
    * thread's {@link android.os.Looper} once the operation is complete.
    * The value provided to the callback indicates whether the cookie was set successfully.
    * You can pass {@code null} as the callback if you don't need to know when the operation
    * completes or whether it succeeded, and in this case it is safe to call the method from a
    * thread without a Looper.
    *
    * @param url the URL for which the cookie is to be set
    * @param value the cookie as a string, using the format of the 'Set-Cookie'
    * HTTP response header
    * @param callback a callback to be executed when the cookie has been set
    */
    public abstract void setCookie(String url, String value, ValueCallback<Boolean> callback);//根据url覆盖cookie某字段的值
    /**
    * Gets the cookies for the given URL.
    *
    * @param url the URL for which the cookies are requested
    * @return value the cookies as a string, using the format of the 'Cookie'
    * HTTP request header
    */
    public abstract String getCookie(String url); //根据url获取cookie
    /**
    * See {@link #getCookie(String)}.
    *
    * @param url the URL for which the cookies are requested
    * @param privateBrowsing whether to use the private browsing cookie jar
    * @return value the cookies as a string, using the format of the 'Cookie'
    * HTTP request header
    * @hide Used by Browser and by WebViewProvider implementations.
    */
    @SystemApi
    public abstract String getCookie(String url, boolean privateBrowsing); //系统api
    /**
    * Gets cookie(s) for a given uri so that it can be set to "cookie:" in http
    * request header.
    *
    * @param uri the WebAddress for which the cookies are requested
    * @return value the cookies as a string, using the format of the 'Cookie'
    * HTTP request header
    * @hide Used by RequestHandle and by WebViewProvider implementations.
    */
    @SystemApi
    public synchronized String getCookie(WebAddress uri) { //系统api
    return getCookie(uri.toString());
    }
    /**
    * Removes all session cookies, which are cookies without an expiration
    * date.
    * @deprecated use {@link #removeSessionCookies(ValueCallback)} instead.
    */
    public abstract void removeSessionCookie(); //清除未过期的cookie
    /**
    * Removes all session cookies, which are cookies without an expiration
    * date.
    * <p>
    * This method is asynchronous.
    * If a {@link ValueCallback} is provided,
    * {@link ValueCallback#onReceiveValue(T) onReceiveValue()} will be called on the current
    * thread's {@link android.os.Looper} once the operation is complete.
    * The value provided to the callback indicates whether any cookies were removed.
    * You can pass {@code null} as the callback if you don't need to know when the operation
    * completes or whether any cookie were removed, and in this case it is safe to call the
    * method from a thread without a Looper.
    * @param callback a callback which is executed when the session cookies have been removed
    */
    public abstract void removeSessionCookies(ValueCallback<Boolean> callback); //坑爹的异步方法
    /**
    * Removes all cookies.
    * @deprecated Use {@link #removeAllCookies(ValueCallback)} instead.
    */
    @Deprecated
    public abstract void removeAllCookie();
    /**
    * Removes all cookies.
    * <p>
    * This method is asynchronous.
    * If a {@link ValueCallback} is provided,
    * {@link ValueCallback#onReceiveValue(T) onReceiveValue()} will be called on the current
    * thread's {@link android.os.Looper} once the operation is complete.
    * The value provided to the callback indicates whether any cookies were removed.
    * You can pass {@code null} as the callback if you don't need to know when the operation
    * completes or whether any cookies were removed, and in this case it is safe to call the
    * method from a thread without a Looper.
    * @param callback a callback which is executed when the cookies have been removed
    */
    public abstract void removeAllCookies(ValueCallback<Boolean> callback); //清除所有cookie
    /**
    * Gets whether there are stored cookies.
    *
    * @return true if there are stored cookies
    */
    public abstract boolean hasCookies(); //获取是否有cookie
    /**
    * See {@link #hasCookies()}.
    *
    * @param privateBrowsing whether to use the private browsing cookie jar
    * @hide Used by Browser and WebViewProvider implementations.
    */
    @SystemApi
    public abstract boolean hasCookies(boolean privateBrowsing); //系统api
    /**
    * Removes all expired cookies.
    * @deprecated The WebView handles removing expired cookies automatically.
    */
    @Deprecated
    public abstract void removeExpiredCookie(); //清除过期的cookie
    /**
    * Ensures all cookies currently accessible through the getCookie API are
    * written to persistent storage.
    * This call will block the caller until it is done and may perform I/O.
    */
    public abstract void flush(); //确保cookie都是写进本地了,会阻塞IO
    /**
    * Gets whether the application's {@link WebView} instances send and accept
    * cookies for file scheme URLs.
    *
    * @return true if {@link WebView} instances send and accept cookies for
    * file scheme URLs
    */
    // Static for backward compatibility.
    public static boolean allowFileSchemeCookies() {
    return getInstance().allowFileSchemeCookiesImpl();
    }
    /**
    * Implements {@link #allowFileSchemeCookies()}.
    *
    * @hide Only for use by WebViewProvider implementations
    */
    @SystemApi
    protected abstract boolean allowFileSchemeCookiesImpl();
    /**
    * Sets whether the application's {@link WebView} instances should send and
    * accept cookies for file scheme URLs.
    * Use of cookies with file scheme URLs is potentially insecure and turned
    * off by default.
    * Do not use this feature unless you can be sure that no unintentional
    * sharing of cookie data can take place.
    * <p>
    * Note that calls to this method will have no effect if made after a
    * {@link WebView} or CookieManager instance has been created.
    */
    // Static for backward compatibility.
    public static void setAcceptFileSchemeCookies(boolean accept) {
    getInstance().setAcceptFileSchemeCookiesImpl(accept);
    }
    /**
    * Implements {@link #setAcceptFileSchemeCookies(boolean)}.
    *
    * @hide Only for use by WebViewProvider implementations
    */
    @SystemApi
    protected abstract void setAcceptFileSchemeCookiesImpl(boolean accept);
坚持原创技术分享,您的支持将鼓励我继续创作!