Webview 66.0.3359.126中IndexedDB写入数据库失败问题咨询
这种坑我之前帮不少开发者踩过——WebView从55.x升级到66.x后,IndexedDB的put方法明明显示执行成功,实际功能却失效,大概率是新版本对IndexedDB的事务管理、存储规则做了更严格的约束,刚好你的代码没跟上这些变化。结合你提供的代码片段,我整理了几个最可能的原因和对应的解决办法:
1. 升级事务的生命周期管理出问题了
WebView 66+对onupgradeneeded回调里的升级事务做了更严格的自动提交规则。如果你的代码在创建对象仓库后,没有显式绑定事务引用,或者操作没有在事务生命周期内完成,就会出现“操作显式成功但数据没写入”的情况——因为事务提前被自动提交回滚了。
比如你原来的代码可能是这样的:
var request = indexedDB.open("library"); request.onupgradeneeded = function() { var db = this.result; // 创建对象仓库 var objectStore = db.createObjectStore("books", { keyPath: "id" }); // 直接在这里put,事务可能提前结束 objectStore.put({ id: 1, title: "Test Book" }); }; request.onsuccess = function() { var db = this.result; var tx = db.transaction("books", "readwrite"); var putReq = tx.objectStore("books").put({ id: 1, title: "Updated" }); putReq.onsuccess = () => console.log("Put成功"); // 假成功 };
修复方案:显式获取升级事务,确保所有操作都绑定到当前事务,并且如果后续要操作数据库,必须等升级事务完成后再进行:
var request = indexedDB.open("library"); request.onupgradeneeded = function(event) { var db = event.target.result; var upgradeTx = event.target.transaction; // 显式拿到升级事务 // 先判断对象仓库是否存在,避免重复创建报错 var objectStore = upgradeTx.objectStore("books") || db.createObjectStore("books", { keyPath: "id" }); // 在升级事务内的操作要监听完成状态 var initPut = objectStore.put({ id: 1, title: "初始数据" }); initPut.onsuccess = () => console.log("升级事务内写入完成"); }; request.onsuccess = function(event) { var db = event.target.result; // 开启读写事务时,一定要传数组格式的对象仓库名 var tx = db.transaction(["books"], "readwrite"); // 务必监听事务的错误和完成事件! tx.onerror = (err) => console.error("事务出错:", err); tx.oncomplete = () => console.log("事务提交完成"); var objectStore = tx.objectStore("books"); var putReq = objectStore.put({ id: 1, title: "更新后的数据" }); putReq.onsuccess = () => console.log("Put操作完成"); putReq.onerror = (err) => console.error("Put操作出错:", err); };
2. WebView存储路径或权限的变更
从WebView 60+开始,Android调整了WebView的存储分区策略,升级后可能出现旧数据库路径无法访问、新数据库因为权限不足无法写入的情况,这也会导致put看似成功但实际没数据。
解决办法:
- 检查你的Android应用是否配置了正确的存储权限,WebView 66+更依赖内部存储,确保应用的
AndroidManifest.xml里相关权限配置正确(比如针对Android 6.0+的动态权限申请)。 - 尝试清除WebView的缓存和存储(在应用设置里操作),排除旧数据库文件损坏的可能。
3. 没监听事务层面的错误
很多开发者只监听了put请求的onsuccess和onerror,但忽略了事务本身的错误。WebView 66+里,只要事务层面出现错误(比如对象仓库不存在、键冲突),整个事务会回滚,而put请求的onsuccess可能只是操作本身执行完了,但最终数据没提交。
关键提醒:一定要给事务加上onerror监听,这才是排查问题的关键——很多时候错误信息会直接告诉你哪里出问题了。
额外调试技巧
用Chrome的远程调试功能(在Chrome地址栏输入chrome://inspect)连接你的WebView,打开DevTools的Application面板,直接查看IndexedDB的内容,确认数据到底有没有写入;同时在控制台里查看所有的错误日志,这些日志往往能帮你快速定位问题。
内容的提问来源于stack exchange,提问作者Adeel Khalid

