Android5.0上运行SQLite数据库出现attempt to write a readonly database的解决方案

简介:

场景

Jni下编译SQLite源码作为数据库,在测试手机:型号(Redmi Note 2) Android版本(5.0.2 LRX22G)系统下使用,尝试写数据库的时候,返回错误信息:attempt to write a readonly database


解决

在sqlite.c文件中查找

ino_t ino; /* Inode number */

修改为

unsigned long long ino; /* Inode number */



错误说明

Store inodes in unsigned long long


In 32 bit ABIs, ino_t is a 32 bit type, while the st_ino field


in struct stat is 64 bits wide in both 32 and 64 bit processes.


This means that struct stat can expose inode numbers that are


truncated when stored in an ino_t.


The SDCard fuse daemon (/system/bin/sdcard) uses raw pointer


values as inode numbers, so on 64 bit devices, we're very likely


to observe inodes that need > 32 bits to represent.


The fileHasMoved function in sqlite compares the stored


inode value with a new one from stat, and when the stored


value is truncated, this check will falsely indicate that


the file has been moved. When the fileHasMoved function


triggers, other functions start returning errors indicating


that the database is in read-only mode.


NOTE: Bionic differs from glibc in that struct stat's st_ino


is *always* 64 bits wide, and not the same width as ino_t.



参考

http://www.jianshu.com/p/30139ef31230


解决过程:

1 怀疑是读写权限的问题,但是其他文件也有读写,明显不成立,并且已经提供了读写的权限:

<uses-permission android:name="android.permission.INTERNET" />


2 怀疑是使用MTP模式共享机身存储到电脑,导致两边同时编辑,通过关闭MTP媒体共享,不成立

Redmi Note 2手机请勿关闭MTP媒体设备,否则需要恢复出厂设置才能够重新共享到电脑。


3 拷贝test.db和test.db-journal文件到Windows系统,并且使用SQLite控制台进行修改,没有任何的

问题。当前使用的是相同的SQLite源码编译的控制台程序。进行数据的插入过程中,会自动删除journal归档文件,并没有提示只读。另外单独拷贝test.db,直接操作,也没有任何的问题。


4 尝试关闭Java层对数据库的读写访问,只是允许NDK层直接操作数据库,防止多线程访问数据库,还是出现同样的结果,当然不知道是否是sqlite3_open与sqlite3_open_v2的接口是否会产生不同的结果,目前采用第一种方法访问数据库。


5 尝试获取Android系统中SQLite的版本,调用getVersion返回1,没有实质上的帮助。


6 是否是其他的Java层获取数据库的连接,没有关闭导致问题的出现?SQliteOpenHelper内部只缓存一个数据库的连接,在多线程的使用过程中,不要频繁的调用close,而应该保存一个唯一的一个访问实例,但是对于多进程之间的访问,也带来问题http://blog.sina.com.cn/s/blog_5de73d0b0102w0g0.html



7 虽然NDK无法修改数据,但是可以读取数据,而Java层却可以轻松的完成数据库的修改操作。


8 尝试调用beginTransaction和endTransaction对数据库的操作进行事务加锁还是没有任何的效果


9 怀疑是Android目录的读取问题,NDK层的SQLite读取数据库文件,发现有问题,但是没有办法找到journal归档文件,因此认为是只读,也是合理的

总结:

    经过上述种种的研究分析,得到如下的猜测:NDK层的SQLite实例在系统开机启动之后,会检查是否存在journal档案。如果是通过程序自动删除该journal档案。但是如果程序无法自动删除,目前怀疑就是因为版本之间的不对称,导致无法删除journal,SQLite数据库因此数据库变成只读的状态。


折中方案:

    NDK层只是负责只读数据,如果有任何的修改,都需要调用Java的接口进行修改数据,虽然有SQLite的源码,但是NDK层不好调试。



    本文转自fengyuzaitu 51CTO博客,原文链接:http://blog.51cto.com/fengyuzaitu/1946701,如需转载请自行联系原作者






相关文章
|
13天前
|
存储 消息中间件 人工智能
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
46 3
|
13天前
|
存储 API Android开发
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
63 4
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
|
2月前
|
存储 Android开发 数据安全/隐私保护
Thanox安卓系统增加工具下载,管理、阻止、限制后台每个APP运行情况
Thanox是一款Android系统管理工具,专注于权限、后台启动及运行管理。支持应用冻结、系统优化、UI自定义和模块管理,基于Xposed框架开发,安全可靠且开源免费,兼容Android 6.0及以上版本。
178 4
|
5月前
|
缓存 Android开发 开发者
Flutter环境配置完成后,如何在Android设备上运行Flutter应用程序?
Flutter环境配置完成后,如何在Android设备上运行Flutter应用程序?
1002 62
|
5月前
|
开发工具 Android开发 开发者
在Android设备上运行Flutter应用程序时,如果遇到设备未授权的问题该如何解决?
在Android设备上运行Flutter应用程序时,如果遇到设备未授权的问题该如何解决?
319 61
|
5月前
|
SQL 数据库连接 数据库
在C++的QT框架中实现SQLite数据库的连接与操作
以上就是在C++的QT框架中实现SQLite数据库的连接与操作的基本步骤。这些步骤包括创建数据库连接、执行SQL命令、处理查询结果和关闭数据库连接。在实际使用中,你可能需要根据具体的需求来修改这些代码。
300 14
|
11月前
|
算法 数据处理 Android开发
掌握安卓性能优化的秘诀:电池寿命与运行效率的提升
【10月更文挑战第6天】 本文深入探讨了安卓应用开发中的性能优化技巧,重点分析了影响电池寿命和运行效率的关键因素,并提供了针对性的优化策略。通过代码优化、资源管理、后台任务处理等方法,开发者可以显著提升应用的续航能力和流畅度。同时,结合具体案例,展示了如何在实际开发中应用这些技巧,确保应用在各种场景下都能保持高效运行。本文旨在为安卓开发者提供实用的性能优化指导,助力其打造更优质的应用体验。
294 2
|
7月前
|
缓存 Java 测试技术
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
839 3
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
|
6月前
|
数据库
【YashanDB数据库】YAS-02079 archive log mode must be enabled when database is in replication mode
YAS-02079 archive log mode must be enabled when database is in replication mode
|
9月前
|
关系型数据库 MySQL 数据库
Python处理数据库:MySQL与SQLite详解 | python小知识
本文详细介绍了如何使用Python操作MySQL和SQLite数据库,包括安装必要的库、连接数据库、执行增删改查等基本操作,适合初学者快速上手。
972 15

热门文章

最新文章