Android WebView Error – Uncaught TypeError: Cannot call method 'getItem' of null at …

昨天在試 Android WebView 這個元件,發現整個速度跟瀏覽器完全沒得比,包括内建瀏覽器、Chrome、Firefox、Opera …。每種瀏覽器的速度都比 WebView 快上許多 … 小蛙跟許多人一樣巴不得把 chrome 塞進 app 裡面!網路上有些人推薦 chromeview,不過有一些 bug 以及對於比較低 API 的 app 是沒辦法使用的!這篇記錄小蛙遇到 WebView 在載入網頁的時候遇到 Uncaught TypeError 錯誤的解決方法。

小蛙之前只拿 WebView 來做簡單的頁面呈現,例如:我的股票精算師的新聞頁面 (讀取 url)、我的郵局便利查的 ATM 及郵局頁面 (讀取 assets)、Micat發現幸福的文章頁面 (讀取 url)。速度感覺沒有瀏覽器快但還算是可以接受!這次小蛙測試了幾個網頁,包括:小蛙的部落格-記下來生活蛙齋奇摩拍賣(會自動轉成手機版) … 等網頁,結構越複雜的網頁就越慢 … 但是特別的是奇摩拍賣手機版網頁,竟然也可以慢到如此誇張 … 不怪 WebView,因為就連直接用 Chrome 開啟都要花很長的一段時間,問題出在整個頁面載入完成之後,又做了大量的 DOM 操作,像是動態選單建立,動態元件 … 等等。奇摩拍賣放進了太多功能,造成整個效能低落 … (也許是小蛙自己的感覺有問題 … )!

webview.png
上圖是奇摩拍賣手機版放入 WebView 的畫面,小小一個頁面上有著非常多功能,左上角的找商品、右上角的會員、中間上方搜尋、中間選單、中間下面拍賣品陳列;但這個頁面其實有兩個部份在 WebView 中開啟的時候發生了錯誤(紅框部份)!小蛙試了很久紅框部份應該要出現動態選單,在這邊卻遲遲未出現,造成該頁面既有功能癱瘓掉 … 下圖才是正常的頁面 (用 Chrome 開啟)

webviw2.png
找了好久找不到問題在哪邊,後來在 Logcat 中發現一行關鍵的錯誤

1
08-08 10:04:45.990: E/Web Console(3324): Uncaught TypeError: Cannot call method 'getItem' of null at http://l.yimg.com/tu/90e25deb72225483a6103a633c757035.js:1

當時小蛙還異想天開的以為是 WebViewClient.onReceivedError 或是 WebViewClient.onLoadResource 丟出這個令人覺得大心的錯誤,如果直接把網址貼上瀏覽器會發生錯誤,把後面的 :1 刪掉就可以正常讀取該 js,那只要在 WebViewClient.onLoadResource 讀取資源的時候,把 :1 這種造成錯誤的字元過濾掉就好了,把動作加上去之後發現,事情絕對沒有笨蛋想的那麼簡單 … 這個錯誤的拋出跟上面提到那兩個 function 一點關係都沒有 … 錯誤依然存在,跑不出來的功能依然跑不出來!
Google 一下發現有很多人都遇到這個問題,解決的方法很簡單,這個錯誤的引起是因為剛剛一開始有提到該網頁是在 DOM 載入之後才開始對 DOM 元素進行操作,這邊有提到 WebSettings.setDomStorageEnabled(boolean)

1
2
public synchronized void setDomStorageEnabled (boolean flag)
Sets whether the DOM storage API is enabled. The default value is false.

預設是不做 DOM 儲存的動作,也就是說在整個網頁載入完成之後並不把 DOM tree 儲存起來,所以導致後續對於 DOM 元素的操作,因為找不到這棵 tree 而發生錯誤,只要加上以下這行

1
wv.getSettings().setDomStorageEnabled(true);

問題就解決了!這次使用 WebView 來做一些東西加上整個切換成 fragment 的方式,應該會遇到不少問題!黃小蛙,加油!

    發佈留言

    發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

    這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料