Introduction – 前言
今天來介紹使用 Android WebView 元件結合 HTML5 API 來開發 WebApp,首先讓我們來看看 WebApp 有哪些優點?
使用 HTML5 開發,理論上跨平台 對於網頁開發之人員,可使用以往熟悉的方法開發 App
奇怪,Web 開發不是標準規範嗎?為什麼說理論上跨平台呢?因為其實各種瀏覽器對於 HTML5 的實作與支援程度並不同。加上有時候為了彌補 HTML5 功能不足,使用了 JavaScript Bridge 技術來呼叫 Native 程式進行溝通,這些作法在跨平台的特性上都是扣分的。但是如果配合有效的底層設計,藉此實作較為泛用的介面,確實可以降低一些跨平台的問題(像是 PhoneGap 的作法)。
當然 WebApp 有優點也有缺點,由於 WebApp 是在瀏覽器中執行,這樣的架構下最大的致命傷就是速度慢。但我們似乎能相信未來的手機運算速度會越來越快,現在 WebApp 的速度慢問題應該或許可能不一定是個重要的問題…….除了剛剛提到的小問題之外,還有一個缺點就是 HTML5 API 威力有限,在實際運用上做不到的事情還挺多的,如果真要用這樣的架構來開發功能比較強大的 App,還是逃不了撰寫原生程式來滿足需求。
我們先來看看下面典型的 WebApp 架構圖,WebApp 主要由程式內嵌的瀏覽器來執行,而 WebView 還可以有一些薄弱的能力與瀏覽器中的 JavaScript Runtime 進行交涉,藉此發展出 JavaScript Bridge 的機制:
在上面的架構圖中發現,其實要學的東西也不少呢。大致上如果你想要開發 WebApp,以下有幾點是具備的技能:
DOM (Document Object Model) 操作 JavaScript HTML5 API CSS3 善用 Library (例如:jQuery, jQuery Mobile, Sencha Touch 2, PhoneGap, Processing.js 等等)
接下來讓我們用 HTML5 API 來實作 Android WebApp。
HTML5 Web Storage API 使用教學
關於 Android WebApp 開發環境建立在此不多著墨,請參考「Android WebApp 開發教學 – HTML5 WebView 行動應用 」這一篇文章。記得要在 Activity Class 中設定 WebView 要開啟 WebStorage 的功能,如下程式碼:
webview
.
getSettings
(
)
.
setJavaScriptEnabled
(
true
)
;
這次要介紹的 HTML5 Web Storage API 可分為 Local Storage 與 Session Storage,兩者之間的差異在於 Session Storage 當瀏覽器關閉時就會被清除,而 Local Storage 則會持續保留。以下我們利用 Local Storage 來實作「聯絡簿 App」之新增與查詢功能,主要會用到以下兩個 HTML5 JavaScript 函式:
// 取得 Local Storage 儲存的資料
window
.
localStorage
.
getItem
(
key
)
;
// 設定資料到 Local Storage 中
window
.
localStorage
.
setItem
(
key
,
value
)
;
此外一提,Web Storage 是採用 Key/Value 的方式操作,用來儲存的 Value 僅能夠為字串格式,這時借用 JSON 便可以加強 Web Storage 之能力(JSON為一種輕量級的資料格式)。但如果您的資料儲存需求更為複雜,那就需要用到 SQL Database 或者 IndexedDB 這些更適合處理資料的 HTML5 API 了。
以下我們使用 Android 2.2 + WebView 元件 + jQuery + HTML5 Web Storage API 實作了簡易「聯絡簿 App」,以下是 index.html 的程式碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html
xmlns
=
"http://www.w3.org/1999/xhtml"
lang
=
"zh-TW"
>
<head>
<meta
http-equiv
=
"Content-Type"
content
=
"text/html; charset=UTF-8"
/>
<title>
HTML5 WebApp Contacts Example
</title>
<script type = "text/javascript" charset = "utf-8" src = "jquery.min.js" > </script>
<script type = "text/javascript" charset = "utf-8" src = "contacts_html5.js" > </script>
</head>
<body>
<h2>
WebApp HTML5 聯絡簿
</h2>
<p>
<input
type
=
"button"
value
=
"刷新聯絡簿"
id
=
"refresh_btn"
/>
</p>
<table
border
=
"1"
>
<thead>
<tr>
<th>
姓名
</th>
<th>
電話
</th>
</tr>
</thead>
<tbody
id
=
"contact_body"
>
</tbody>
</table>
<p>
姓名:
<input
type
=
"text"
name
=
"name_txt"
id
=
"name_txt"
/>
</p>
<p>
電話:
<input
type
=
"text"
name
=
"tel_txt"
id
=
"tel_txt"
/>
</p>
<p>
<input
type
=
"button"
value
=
"新增"
id
=
"create_btn"
/>
</p>
</body>
</html>
為了將畫面與邏輯分離,上述的 index.html 僅實作的顯示使用者介面,與業務邏輯相關的程式碼我們把它寫在 contacts_html5.js 檔案中。以下是 contacts_html5.js 的內容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// 網頁都載入完畢後才會執行
$
(
document
)
.
ready
(
function
(
)
{
// 由 Local Storage 取出聯絡簿,不存在就建立資料庫
var
jsonString
=
window
.
localStorage
.
getItem
(
'myContacts'
)
;
var
contacts
=
JSON
.
parse
(
jsonString
)
;
if
(
contacts
===
null
||
typeof
(
contacts
)
!==
'object'
)
{
// 輸出 Log 與建立資料庫
console
.
log
(
'Create Local Storage.'
)
;
var
contacts
=
[
]
;
var
jsonString
=
JSON
.
stringify
(
contacts
)
;
window
.
localStorage
.
setItem
(
'myContacts'
,
jsonString
)
;
}
// 重新讀取手機聯絡簿
$
(
'#refresh_btn'
)
.
click
(
function
(
)
{
// 先清空table
$
(
'#contact_body'
)
.
children
(
)
.
remove
(
)
;
//由 Local Storage 抓資料回填
var
jsonString
=
window
.
localStorage
.
getItem
(
'myContacts'
)
;
var
contacts
=
JSON
.
parse
(
jsonString
)
;
for
(
i
in
contacts
)
{
$
(
'#contact_body'
)
.
append
(
'<tr><td>'
+
contacts
[
i
]
.
displayName
+
'</td><td>'
+
contacts
[
i
]
.
phoneNumber
+
'</td></tr>'
)
;
}
}
)
;
// 建立新人員
$
(
'#create_btn'
)
.
click
(
function
(
)
{
var
newContact
=
{
}
;
newContact
.
displayName
=
$
(
'#name_txt'
)
.
val
(
)
;
newContact
.
phoneNumber
=
$
(
'#tel_txt'
)
.
val
(
)
;
// 由 Local Storage 取出聯絡簿
var
jsonString
=
window
.
localStorage
.
getItem
(
'myContacts'
)
;
var
contacts
=
JSON
.
parse
(
jsonString
)
;
// 新增後回存
contacts
.
push
(
newContact
)
;
window
.
localStorage
.
setItem
(
'myContacts'
,
JSON
.
stringify
(
contacts
)
)
;
$
(
'#name_txt'
)
.
val
(
''
)
;
$
(
'#tel_txt'
)
.
val
(
''
)
;
}
)
;
}
)
;
程式執行後我們可以按下「刷新聯絡簿」來讀取 Local Storage 中的 JSON 轉換後顯示在 <table> 中,也可以輸入姓名與電話欄位後安下「新增」來加入新的人員名單,此外將 App 關閉後再次進入,仍然能夠由 Local Storage 讀取之前儲存的資料。下圖為 WebApp 程式在 Android 模擬器的執行結果:
由於是使用 HTML5 來實作資料的儲存,這個網頁也能夠由支援 HTML5 的瀏覽器開啟而獲得一樣的功能。以下是使用 Google Chrome 開啟的結果,開啟後按下「F12」啟動開發者工具,我們可以在 Resources 標籤中的 Local Storage 看到經由 HTML5 儲存的資料:
實作這樣的「聯絡簿」功能實在有些無聊,更何況手機本來就有聯絡簿了,何必自己搞一個呢?說的也是,如果是結合手機聯絡簿進行管理不是更好嗎?但要讀手機聯絡簿 HTML5 API 似乎沒這招,難道用 WebView 實作的 WebApp 就得這樣放棄了嗎?別忘了我們還有 JavaScript Bridge 的技術可以用,下一篇文章就來給各位介如何在 WebApp 加入 PhoneGap 來突破 HTML5 的限制。
Reference – 參考資料