Cordova - 存储
Cordova - 客户端存储选项
Section titled “Cordova - 客户端存储选项”Cordova 应用程序可以利用各种客户端存储机制在设备本地存储数据。这使得离线功能成为可能,通过缓存数据提高性能,并允许保存用户偏好设置。本教程重点介绍 localStorage,一种简单的键值对存储方式,并简要提及其他选项。
使用 localStorage
Section titled “使用 localStorage”localStorage 是 Web Storage API 的一部分,在所有现代 Web 视图中都可用。它允许您将数据存储为键值对(key-value pairs),其中键(key)和值(value)都是字符串。
步骤 1 - 准备 UI
Section titled “步骤 1 - 准备 UI”在 www/index.html 中,创建与 localStorage 交互的按钮和一个 div 用于显示存储的数据或消息。
<body> <h1>localStorage Demo</h1> <input type="text" id="dataKey" placeholder="Enter Key (e.g., userTheme)"> <input type="text" id="dataValue" placeholder="Enter Value (e.g., dark)"> <br><br> <button id="setItemBtn">SET Item</button> <button id="getItemBtn">GET Item by Key</button> <button id="removeItemBtn">REMOVE Item by Key</button> <button id="listAllBtn">LIST All Items</button> <button id="clearAllBtn">CLEAR All Storage</button>
<div id="storageOutput" style="margin-top: 20px; border: 1px solid #ccc; padding: 10px;"> Storage data will appear here... </div>
<script src="cordova.js"></script> <script src="js/index.js"></script></body>步骤 2 - 实现 JavaScript 逻辑
Section titled “步骤 2 - 实现 JavaScript 逻辑”在 www/js/index.js 中,直接访问 localStorage。它立即可用,不需要等待 deviceready 事件(尽管您的应用程序逻辑可能需要)。
// No 'deviceready' needed for localStorage itself, but good practice for app structure.// localStorage 本身不需要 deviceready,但这对于应用程序结构而言是个好的实践。document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() { console.log('Device is ready. localStorage is available.'); console.log('设备已就绪。localStorage 可用。');
const keyInput = document.getElementById('dataKey'); const valueInput = document.getElementById('dataValue'); const outputDiv = document.getElementById('storageOutput');
document.getElementById('setItemBtn').addEventListener('click', () => { const key = keyInput.value.trim(); const value = valueInput.value.trim(); if (key && value) { // For non-string data, serialize to JSON // 对于非字符串数据,需要序列化为 JSON // For this example, we assume simple strings or let users manage JSON manually. // 在本示例中,我们假设使用简单字符串或让用户手动处理 JSON。 localStorage.setItem(key, value); outputDiv.textContent = `Item set: ${key} = ${value}`; console.log(`localStorage.setItem: ${key} = ${value}`); } else { outputDiv.textContent = 'Please provide both key and value.'; outputDiv.textContent = '请提供键和值。'; } });
document.getElementById('getItemBtn').addEventListener('click', () => { const key = keyInput.value.trim(); if (key) { const value = localStorage.getItem(key); if (value !== null) { outputDiv.textContent = `Item found: ${key} = ${value}`; console.log(`localStorage.getItem(${key}): ${value}`); } else { outputDiv.textContent = `Item with key '${key}' not found.`; outputDiv.textContent = `未找到键为 '${key}' 的项。`; console.log(`localStorage.getItem(${key}): null`); } } else { outputDiv.textContent = 'Please provide a key to retrieve.'; outputDiv.textContent = '请提供要检索的键。'; } });
document.getElementById('removeItemBtn').addEventListener('click', () => { const key = keyInput.value.trim(); if (key) { localStorage.removeItem(key); outputDiv.textContent = `Item with key '${key}' removed (if it existed).`; outputDiv.textContent = `已移除键为 '${key}' 的项(如果存在)。`; console.log(`localStorage.removeItem: ${key}`); } else { outputDiv.textContent = 'Please provide a key to remove.'; outputDiv.textContent = '请提供要移除的键。'; } });
document.getElementById('listAllBtn').addEventListener('click', () => { outputDiv.innerHTML = '<h3>All localStorage Items:</h3>'; outputDiv.innerHTML = '<h3>所有 localStorage 项:</h3>'; if (localStorage.length === 0) { outputDiv.innerHTML += '<p>localStorage is empty.</p>'; outputDiv.innerHTML += '<p>localStorage 为空。</p>'; return; } const ul = document.createElement('ul'); for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); const value = localStorage.getItem(key); const li = document.createElement('li'); li.textContent = `${key}: ${value}`; ul.appendChild(li); } outputDiv.appendChild(ul); console.log('localStorage contents:', localStorage); console.log('localStorage 内容:', localStorage); });
document.getElementById('clearAllBtn').addEventListener('click', () => { localStorage.clear(); outputDiv.textContent = 'All items cleared from localStorage.'; outputDiv.textContent = 'localStorage 中的所有项已清除。'; console.log('localStorage.clear() executed.'); console.log('localStorage.clear() 已执行。'); });}localStorage API 方法
Section titled “localStorage API 方法”| 方法 | 描述 |
|---|---|
setItem(key, value) | 添加或更新一个键值对。key 和 value 都会被转换为字符串。 |
getItem(key) | 检索与 key 关联的值。如果 key 不存在,则返回 null。 |
removeItem(key) | 移除与 key 关联的键值对。 |
key(index) | 返回给定整数索引处的键名。键的顺序不保证固定,可能因浏览器引擎而异。请勿依赖此顺序。 |
length (property) | 返回存储的键值对数量。 |
clear() | 移除所有键值对。 |
关于 localStorage 的重要注意事项
Section titled “关于 localStorage 的重要注意事项”- 仅限字符串数据:
localStorage将所有数据存储为字符串。如果需要存储对象或数组,必须先将它们序列化为 JSON 字符串(例如,使用JSON.stringify()),然后在检索后进行解析(使用JSON.parse())。 - 同步:
localStorage操作是同步的,这意味着它们会阻塞主线程。对于复杂的数据或频繁的操作,这可能会影响性能。对于要求更高的场景,请考虑使用异步替代方案。 - 存储限制:
localStorage有存储限制,通常每个源(origin)约为 5-10MB,具体可能因浏览器/WebView 而异。 - 安全性:
localStorage中的数据未加密,可以被同一源上运行的任何脚本访问。请勿直接存储敏感信息,如密码或令牌。 - 持久性:
localStorage中的数据会一直存在,直到被应用程序或用户(例如,通过清除浏览器数据)明确清除为止。即使应用程序更新,数据也不会被清除。 - 键的顺序: 如前所述,
localStorage.key(index)不保证特定的顺序。如果顺序很重要,请自行管理(例如,存储一个键数组)。
Cordova 中的其他存储选项
Section titled “Cordova 中的其他存储选项”虽然 localStorage 对于简单数据很方便,但 Cordova 应用程序也可以使用更高级的存储解决方案:
sessionStorage: 类似于localStorage,但数据在会话结束时(例如,应用程序关闭时)会被清除。通常不用于移动应用程序中的持久性数据。- IndexedDB: 一个更强大、异步、支持事务的 NoSQL 数据库,内置于现代浏览器/Web 视图中。适用于存储大量结构化数据。直接使用可能很复杂;PouchDB 或 Dexie.js 等库可以简化其使用。
- WebSQL (已废弃): 一个较旧的 API,提供 SQL 数据库访问。它已被废弃,不推荐用于新项目。支持不一致。
- 用于存储的 Cordova 插件:
-
cordova-sqlite-storage: 提供原生 SQLite 数据库访问。非常适合关系型数据、大型数据集和复杂查询。操作是异步的。
-
cordova-plugin-nativestorage: 提供原生、异步的键值存储,对于某些用例(尤其是在某些平台上)可能比localStorage性能更好或更健壮。适用于偏好设置和少量数据。
-
cordova-plugin-file: 用于在设备的文件系统中以文件形式存储数据。适用于二进制数据、大型 Blob 或用户生成的文件。
选择合适的存储方式
Section titled “选择合适的存储方式”最佳的存储选择取决于您应用程序的需求:
- 简单的键值对、少量数据、非敏感的用户偏好设置:
localStorage可能足够。 - 较大的结构化数据、离线功能、复杂查询: IndexedDB(配合辅助库)或
cordova-sqlite-storage。 - 存储文件(图像、文档等):
cordova-plugin-file。 - 改进的异步键值存储:
cordova-plugin-nativestorage。
对于更高级的存储需求,请查阅上述插件及其文档。理解简单性、性能、存储容量和数据结构能力之间的权衡是关键。