首先說下爲啥會產生這個問題,其實瀏覽器是有一套緩存機制的,在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 頁面的賬號同步問題。