1. 取Cookie的API
[java]
CookieManager.getInstance().getCookie(url);
2.CookieManager的getInstance()
[java]
/** * Gets the singleton CookieManager instance. If this method is used * before the application instantiates a {@link WebView} instance, * {@link CookieSyncManager#createInstance(Context)} must be called * first. * * @return the singleton CookieManager instance */ public static synchronized CookieManager getInstance() { return WebViewFactory.getProvider().getCookieManager(); }
3.WebViewFactory是个工厂模式
[java]
static synchronized WebViewFactoryProvider getProvider() { // For now the main purpose of this function (and the factory abstraction) is to keep // us honest and minimize usage of WebViewClassic internals when binding the proxy. if (sProviderInstance != null) return sProviderInstance; sProviderInstance = getFactoryByName(DEFAULT_WEB_VIEW_FACTORY); if (sProviderInstance == null) { if (DEBUG) Log.v(LOGTAG, "Falling back to explicit linkage"); sProviderInstance = new WebViewClassic.Factory(); } return sProviderInstance; }
4.层层嵌套,最后生成的instance是CookieManagerClassic
[java]
@Override public CookieManager getCookieManager() { return CookieManagerClassic.getInstance(); }
5. getCookie方法 实现在CookieManagerClassic上
[java]
@Override public String getCookie(String url) { return getCookie(url, false); }
@Override public String getCookie(String url, boolean privateBrowsing) { WebAddress uri; try { uri = new WebAddress(url); } catch (ParseException ex) { Log.e(LOGTAG, "Bad address: " + url); return null; } return nativeGetCookie(uri.toString(), privateBrowsing); }
6. nativeGetCookie定义在CookieManager.cpp里
[java]
7. WebCookieJar.cpp中,定义了从哪里去取得Cookie情报
[java]
WebCookieJar* WebCookieJar::get(bool isPrivateBrowsing) { MutexLocker lock(instanceMutex); if (!isFirstInstanceCreated && fileSchemeCookiesEnabled) net::CookieMonster::EnableFileScheme(); isFirstInstanceCreated = true; scoped_refptr<WebCookieJar>* instancePtr = instance(isPrivateBrowsing); if (!instancePtr->get()) *instancePtr = new WebCookieJar(databaseDirectory(isPrivateBrowsing)); return instancePtr->get(); }
[java]
static std::string databaseDirectory(bool isPrivateBrowsing) { static const char* const kDatabaseFilename = "/webviewCookiesChromium.db"; static const char* const kDatabaseFilenamePrivateBrowsing = "/webviewCookiesChromiumPrivate.db"; std::string databaseFilePath = databaseDirectory(); databaseFilePath.append(isPrivateBrowsing ? kDatabaseFilenamePrivateBrowsing : kDatabaseFilename); return databaseFilePath; }
※Android3.0以上是webviewCookiesChromium.db, 以下是WebView.db文件
8.最后读取Cookie情报发生在cookie_monster.cc。 额,最后调到C++, 去读.db文件
[java]
std::string CookieMonster::GetCookiesWithOptions(const GURL& url, const CookieOptions& options) { base::AutoLock autolock(lock_); InitIfNecessary(); if (!HasCookieableScheme(url)) { return std::string(); } TimeTicks start_time(TimeTicks::Now()); // Get the cookies for this host and its domain(s). std::vector<CanonicalCookie*> cookies; FindCookiesForHostAndDomain(url, options, true, &cookies); std::sort(cookies.begin(), cookies.end(), CookieSorter); std::string cookie_line; for (std::vector<CanonicalCookie*>::const_iterator it = cookies.begin(); it != cookies.end(); ++it) { if (it != cookies.begin()) cookie_line += "; "; // In Mozilla if you set a cookie like AAAA, it will have an empty token // and a value of AAAA. When it sends the cookie back, it will send AAAA, // so we need to avoid sending =AAAA for a blank token value. if (!(*it)->Name().empty()) cookie_line += (*it)->Name() + "="; cookie_line += (*it)->Value(); } histogram_time_get_->AddTime(TimeTicks::Now() - start_time); VLOG(kVlogGetCookies) << "GetCookies() result: " << cookie_line; return cookie_line; }