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






相关文章
|
6月前
|
XML 数据库 Android开发
Android数据库的使用(增删改查)
本文介绍了一个简单的数据库操作Demo,包含创建数据库、增删改查功能。通过5个按钮分别实现创建数据库、插入数据、删除数据、更新数据和查询数据的操作。代码结构清晰,适合初学者学习Android SQLite数据库基础操作。
197 5
|
6月前
|
数据库 Android开发
Android外部数据库的引用
简介:本文介绍了在Android项目中引用外部数据库的方法。首先,将现成的数据库文件放入项目的`assets`文件夹中(需手动创建)。其次,在APP引导界面通过代码将数据库拷贝至App目录下,确保数据库可用。最后,对数据库进行增删改查等操作。关键步骤包括判断数据库是否存在、使用`AssetManager`读取数据库文件并写入App私有目录,实现外部数据库的顺利集成与使用。
|
6月前
|
数据库 Android开发 开发者
Android常用的room增删改查语句(外部数据库)
本文分享了将一个原生数据库驱动的单词APP重构为使用Room库的过程及遇到的问题,重点解决了Room中增删改查的常用语句实现。文章通过具体示例(以“forget”表为例),详细展示了如何定义实体类、Dao接口、Database类以及Repository和ViewModel的设计与实现。同时,提供了插入、删除、更新和查询数据的代码示例,包括模糊查询、分页加载等功能。此外,针对外部数据库导入问题,作者建议可通过公众号“计蒙不吃鱼”获取更多支持。此内容适合有一定Room基础的开发者深入学习。
224 0
Android常用的room增删改查语句(外部数据库)
|
8月前
|
监控 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) 系统信息获取如屏幕截图和录屏。通过这些功能,用户可高效调试和管理安卓设备。
|
8月前
|
数据库
【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
|
开发框架 前端开发 Android开发
探索安卓和iOS应用开发中的跨平台解决方案
【10月更文挑战第42天】在移动应用开发的广阔天地中,安卓和iOS系统如同两座巍峨的山峰,分别占据着半壁江山。开发者们在这两座山峰之间穿梭,努力寻找一种既能节省资源又能提高效率的跨平台开发方案。本文将带你走进跨平台开发的世界,探讨各种解决方案的优势与局限,并分享一些实用的代码示例,助你在应用开发的道路上更加游刃有余。
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
298 7
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台解决方案
【9月更文挑战第27天】在移动应用开发的广阔天地中,安卓和iOS两大操作系统如同双子星座般耀眼。开发者们在这两大平台上追逐着创新的梦想,却也面临着选择的难题。如何在保持高效的同时,实现跨平台的开发?本文将带你探索跨平台开发的魅力所在,揭示其背后的技术原理,并通过实际案例展示其应用场景。无论你是安卓的忠实拥趸,还是iOS的狂热粉丝,这篇文章都将为你打开一扇通往跨平台开发新世界的大门。
427 8
|
安全 搜索推荐 程序员
深入探索Android系统的碎片化问题及其解决方案
在移动操作系统的世界中,Android以其开放性和灵活性赢得了广泛的市场份额。然而,这种开放性也带来了一个众所周知的问题——系统碎片化。本文旨在探讨Android系统碎片化的现状、成因以及可能的解决方案,为开发者和用户提供一种全新的视角来理解这一现象。通过分析不同版本的Android系统分布、硬件多样性以及更新机制的影响,我们提出了一系列针对性的策略,旨在减少碎片化带来的影响,提升用户体验。
|
NoSQL 关系型数据库 MySQL
AWS Database Migration Service 助力数据库搬迁
AWS Database Migration Service 助力数据库搬迁