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,如需转载请自行联系原作者






相关文章
|
4月前
|
存储 消息中间件 人工智能
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
【03】AI辅助编程完整的安卓二次商业实战-本地构建运行并且调试-二次开发改注册登陆按钮颜色以及整体资源结构熟悉-优雅草伊凡
195 3
|
4月前
|
存储 API Android开发
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
256 4
【02】完整的安卓二次商业实战-配置gradle-构建打包原生安卓项目-调试本地运行模拟器-优雅草伊凡
|
9月前
|
缓存 Android开发 开发者
Flutter环境配置完成后,如何在Android设备上运行Flutter应用程序?
Flutter环境配置完成后,如何在Android设备上运行Flutter应用程序?
1801 62
|
9月前
|
开发工具 Android开发 开发者
在Android设备上运行Flutter应用程序时,如果遇到设备未授权的问题该如何解决?
在Android设备上运行Flutter应用程序时,如果遇到设备未授权的问题该如何解决?
610 61
|
6月前
|
存储 Android开发 数据安全/隐私保护
Thanox安卓系统增加工具下载,管理、阻止、限制后台每个APP运行情况
Thanox是一款Android系统管理工具,专注于权限、后台启动及运行管理。支持应用冻结、系统优化、UI自定义和模块管理,基于Xposed框架开发,安全可靠且开源免费,兼容Android 6.0及以上版本。
767 4
|
8月前
|
XML 数据库 Android开发
Android数据库的使用(增删改查)
本文介绍了一个简单的数据库操作Demo,包含创建数据库、增删改查功能。通过5个按钮分别实现创建数据库、插入数据、删除数据、更新数据和查询数据的操作。代码结构清晰,适合初学者学习Android SQLite数据库基础操作。
271 5
|
8月前
|
数据库 Android开发
Android外部数据库的引用
简介:本文介绍了在Android项目中引用外部数据库的方法。首先,将现成的数据库文件放入项目的`assets`文件夹中(需手动创建)。其次,在APP引导界面通过代码将数据库拷贝至App目录下,确保数据库可用。最后,对数据库进行增删改查等操作。关键步骤包括判断数据库是否存在、使用`AssetManager`读取数据库文件并写入App私有目录,实现外部数据库的顺利集成与使用。
115 2
|
8月前
|
数据库 Android开发 开发者
Android常用的room增删改查语句(外部数据库)
本文分享了将一个原生数据库驱动的单词APP重构为使用Room库的过程及遇到的问题,重点解决了Room中增删改查的常用语句实现。文章通过具体示例(以“forget”表为例),详细展示了如何定义实体类、Dao接口、Database类以及Repository和ViewModel的设计与实现。同时,提供了插入、删除、更新和查询数据的代码示例,包括模糊查询、分页加载等功能。此外,针对外部数据库导入问题,作者建议可通过公众号“计蒙不吃鱼”获取更多支持。此内容适合有一定Room基础的开发者深入学习。
283 0
Android常用的room增删改查语句(外部数据库)
|
11月前
|
缓存 Java 测试技术
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
1654 3
【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
|
10月前
|
监控 Shell Linux
Android调试终极指南:ADB安装+多设备连接+ANR日志抓取全流程解析,覆盖环境变量配置/多设备调试/ANR日志分析全流程,附Win/Mac/Linux三平台解决方案
ADB(Android Debug Bridge)是安卓开发中的重要工具,用于连接电脑与安卓设备,实现文件传输、应用管理、日志抓取等功能。本文介绍了 ADB 的基本概念、安装配置及常用命令。包括:1) 基本命令如 `adb version` 和 `adb devices`;2) 权限操作如 `adb root` 和 `adb shell`;3) APK 操作如安装、卸载应用;4) 文件传输如 `adb push` 和 `adb pull`;5) 日志记录如 `adb logcat`;6) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。

热门文章

最新文章