WebView寫入資料到 localStorage總結
最近專案中使用了 Hybrid 的框架,也通過 JSBridge 搭建了 WebView 與 JavaScript 的通訊,但是據前端說收發訊息比較繁瑣,而另外一種 localStorage 的方法非常簡單,我心裡想:既然我已經掌握了一種方法了,為何不再學一下另一種方法?於是就簡單去看了看,得到了如下方法:
//1.拼接 JavaScript 程式碼
String key= "userInfo";
User user = new User();
user.setName("Vicent");
user.setPhone(18888886666);
String value = new Gson(). toJson();
String js = "window.localStorage.setItem("+key+",'" + value + "');";
String jsUrl = "javascript:(function({
var localStorage = window.localStorage;
localStorage.setItem("+key+",'" + value + "')
})()";
//2.根據不同版本,使用不同的 API 執行 Js
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWebView. evaluateJavascript(js, null);
} else {
mWebView.loadUrl(jsUrl);
mWebView.reload();
}
經過了解,setItem 方法類似於 Map 物件一般,是以 key—value 鍵值對儲存的,取出這個value的方法如下:
window.localStorage.getItem('userInfo')
當然,取值不用我們操心,前端肯定相當熟練了!那麼直接用嗎?不,至少我們需要對 WebView 設定一些函式,如下:
mWebView = (WebView) this.findViewById(R.id.webview);
WebSettings settings = mWebView.getSettings();
settings.setJavaScriptEnabled(true );
//settings.setPluginsEnabled(true);
/***開啟本地快取提供JS呼叫**/
mWebView.getSettings().setDomStorageEnabled(true);
// Set cache size to 8 mb by default. should be more than enough
mWebView.getSettings().setAppCacheMaxSize(1024*1024*8);
// This next one is crazy. It's the DEFAULT location for your app's cache
// But it didn't work for me without this line.
// UPDATE: no hardcoded path. Thanks to Kevin Hawkins
String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
mWebView.getSettings().setAppCachePath(appCachePath);
mWebView.getSettings().setAllowFileAccess(true);
mWebView.getSettings().setAppCacheEnabled(true);
做了這麼多,終於可以了嗎?由於我們需要在載入html以後,html需要顯示使用者資訊,所以我們需要在 mWebView.loadUrl(“www.* * *”) 以後立即傳給html,經過執行後卻取出值為 null ,這是什麼情況呢?哪裡不對嗎?
經過請教後得知,原因如下:
是因為一開始就執行寫入資料到 localStorage 的存值操作,那時候頁面還沒有渲染出來,執行的 js 找不到宿主,因此寫入資料失敗!
那麼,什麼時候寫入比較好呢?我首先想到的是通過 Handler 的延遲執行方法,來寫入資料,但是延遲時間多少比較合適呢?答案還得從WebView中來尋找!
private boolean inWrited = false;
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if(!inWrited){
setData(webView);
inWrited = true;
}
}
});
private void setData(WebView mWebView) {
//1.拼接 JavaScript 程式碼
String key= "userInfo";
User user = new User();
user.setName("Vicent");
user.setPhone(18888886666);
String value = new Gson().toJson();
String js = "window.localStorage.setItem("+key+",'" + value + "');";
String jsUrl = "javascript:(function({
var localStorage = window.localStorage;
localStorage.setItem("+key+",'" + value + "')
})()";
//2.根據不同版本,使用不同的 API 執行 Js
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWebView.evaluateJavascript(js, null);
} else {
mWebView.loadUrl(jsUrl);
mWebView.reload();
}
}
以上則是在 WebView 在載入 html 檔案後立即寫入資料到 localStorage 。而 js檔案在設定使用者資訊的時候,取值的時候也再也不會取不出來了!
上面的方法幾乎全是大神分享的,主要是自己對WebView不夠熟悉,一開始我以為寫入資料到 localStorage 這個方法失效了,後來確實相信是自己操作的姿勢不對。在知道寫入 localStorage 需要延遲時也沒有想到 WebViewClient 的相關方法,儘管這些方法都是在網上看過的,但是因為自己從來沒有使用過這些方法,所以需要用的時候一時意識不到。因此做一個記錄,以後自己有時間也可以多來看看!