1. 程式人生 > >WebView寫入資料到 localStorage總結

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 的相關方法,儘管這些方法都是在網上看過的,但是因為自己從來沒有使用過這些方法,所以需要用的時候一時意識不到。因此做一個記錄,以後自己有時間也可以多來看看!

參考文章: