首先说下为啥会产生这个问题,其实浏览器是有一套缓存机制的,在android中,我们可以指定webview 的缓存路径,默认是在
data/data/包名/app_webview/Cookies 文件,cookies就是cookie存储的地方。前端在使用js等做缓存时,是不会立即缓存到cookies中的,有一个延时操作,大概十几秒吧,天哪要十几秒,这要出多少bug啊。所以就有了下文。
刚开始我一直以为是前端小弟技术不精,没有认真对待这个问题,后来查了下,确实会有这个问题。并且在代码中用原生代码去缓存一条cookie基本就是秒存。那里来的延时之说,所以当时想法是,你们不是做不了么,那好啊,你把参数给我,我来存你来取,不就好了,前端调用setCookio方法把参数传给android.
private void initCooKie() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.createInstance(this);
}
cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
}
public class JavaScriptinterface {
Context context;
public JavaScriptinterface(Context c) {
context = c;
}
@JavascriptInterface
public void setCookie(String url, String cookie) {
Message message = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("key", url);
bundle.putString("value", cookie);
message.setData(bundle);
message.what=2;
handler.sendMessage(message);
}
}
记得webView.addJavascriptInterface(new JavaScriptinterface(this), "android");
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 2) {
Bundle bundle = msg.getData();
String key = bundle.getString("key");
String value = bundle.getString("value");
cookieManager.setCookie(key, value);
cookieManager.setCookie("username", "username=987654321usernameKey", new ValueCallback<Boolean>() {
@Override
public void onReceiveValue(Boolean aBoolean) {
Log.d(TAG, "onDE_ReceiveValue: " + aBoolean);
}
});
CookieSyncManager.getInstance().sync();
Log.d(TAG, "onJs cookie: cook key:" +key +"---value:" + cookieManager.getCookie(key));
Log.d(TAG, "setCookie: username:" + cookieManager.getCookie("username"));
cookieManager.
}
}
};
这里username的那条cookie是我本地测试用的,用于对比数据。现在说下Cookies文件 它其实是一个数据库文件后缀名是.db
可悲的是我用Navicat Premium 打不开 提示有无效字符。用studio 打开提示编码问题反正是一对乱码,这里推荐一个studio 工具
Database navigator 用于查看数据库工具很好用,然后用它打开数据库,效果如下:
这个就是Cookies这个表里的数据字段。那么问题来了,这里可以看到,刚才我们存了一条值key为(username) value为(username=987654321usernameKey)的数据,表里好像没有啊,其实它会自动保存为两条数据了name 和 value “=” 左边为name (username)右边为 value (987654321usernameKey)
key值“username” 既host_key 的值,现在注意到一个问题,expires_utc的值为0,我们看到表最后有两条是不为零的,那是js存的,既,过期时间,并且我查了好长时间,没有看到使用原生方法如何去设置cookie的过期时间的方法,如果有哪位伙伴知道如何用原生存希望留言告诉我下,不胜感激。
这有点尴尬啊,还是解决不了问题啊,因为存的是登录信息,总要给个过期时间,没有过期时间等于没存么。
后来在staskoverflow 上看到有人说在
onPageFinished 方法内添加 CookieSyncManager.getInstance().sync(); ,试了下果然可以,那么我们只要把之前的逻辑修改下就好了,js还是照样去保存cookie,保存完成后,调下原生方法,原生的方法再去同步下cookie 既调用CookieSyncManager.getInstance().sync(),这样就可以实时保存cookie不会出现延时的问题了。
到这里我的问题就算解决了。
那么我们把问题扩展下,就是可以用这个来实现android 原生和html 页面的账号同步问题。