我需要将一个具有 native 登录屏幕的应用程序与在 webview (混合应用程序)内运行的应用程序的其余部分集成。这听起来像是一种常见的方法,但我在将 session 数据(cookie)从 native 代码传输到 webview 时遇到问题,我认为这与 CookieManager 的异步行为有关。
有时,在某些设备上,cookie 要么被删除,要么不应用。 据我所知,这可能是因为removeSessionCookie、setCookie 和sync 在它们自己的线程中异步运行。我不太理解来自其他编程语言的 Java 中的这一点,因为似乎没有任何钩子(Hook)可以知道任务何时完成 EG 回调、事件、asyc/await 等。
所以问题是你如何知道 Android/Java 中的异步任务何时完成? 我遇到过同步块(synchronized block)语法,但它看起来不会等待诸如removeSessionCookie之类的事情完成。
我的代码看起来有点像这样:
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.removeSessionCookie(); // problem
CookieSyncManager.getInstance().sync(); // maybe problem
List<Cookie> cookies = httpClient.getCookieStore().getCookies();
for (int i = 0; i < cookies.size(); i++) {
Cookie cookie = cookies.get(i);
String cookieString = cookie.getName() + "=" + cookie.getValue();
cookieManager.setCookie(url, cookieString);
}
CookieSyncManager.getInstance().sync();
最佳答案
不幸的是,CookieManager
API 设计使这变得困难/不可能。 CookieSyncManager
在这里根本不相关;它只处理内存中的 cookie 数据库和存储在磁盘上的数据库之间的同步。对其调用 sync()
不会产生任何影响; WebView
和 CookieManager
都已经共享内存数据库,并且在实际进行更改时立即看到彼此的更改。
通常,异步方法会提供某种回调或等待其完成的方式,但 removeSessionCookie()
却不会。实际上,在经典 WebView 的某些版本(从 Honeycomb 直到 JB)的代码中确实实现了这样的方法,但它不是公共(public) API 方法,您必须通过反射访问它,并且它不适用于新的 WebView KK及以上。如果你真的想调用它,那就是 void waitForCookieOperationsToComplete()
,但我不建议这样做。
你为什么要调用removeSessionCookie()
?最简单的解决办法就是不使用它; CookieManager
API 的其余部分按照您的预期运行。您也不需要显式调用 CookieSyncManager.sync()
。您是否遇到了导致您添加这些调用的问题,或者您是否从某处复制了它们?
如果您支持较旧的操作系统版本,这会更加复杂;从 Cupcake 到 Gingerbread,CookieManager
使用的网络堆栈不同,API 的行为也不同,因此这里实际上有三个目标版本:直到 Gingerbread、Honeycomb 到 Jellybean,然后是 KitKat 及更高版本......
关于android - CookieManager-如何管理异步方法-removeSessionCookies,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20338573/