I need to maintain a data table of string columns with full text searching enabled for all the columns.
I understand from Android documentation:
A virtual table behaves similarly to a SQLite table, but reads and writes to an object in memory via callbacks, instead of to a database file.
Would it be safe to use a SQLite virtual table for the purpose and access the table from main UI thread on android without getting an ANR?
Or should I go for one of the third party options like:
答案 0 :(得分:1)
来自The Virtual Table Mechanism Of SQLite:
从SQL语句的角度来看,虚拟表对象看起来像任何其他表或视图。
但在幕后,虚拟表上的查询和更新会调用虚拟表对象的回调方法,而不是读取和写入数据库文件。
因此,从Android角度来看,SQLite Virtual表的行为与任何其他表或视图完全相同,并且根据the documentation about ANRs:
(...)
在您的应用执行可能冗长的操作的任何情况下,您都不应该在UI线程上执行工作,而是创建一个工作线程并在那里完成大部分工作。这使得UI线程(驱动用户界面事件循环)保持运行,并阻止系统断定您的代码已冻结。因为这种线程通常是在类级别完成的,所以您可以将响应性视为类问题。 (将此与基本代码性能进行比较,这是方法级别的考虑因素。)
在Android中,应用程序响应性由活动管理器和Window Manager系统服务监视。 Android会在检测到以下某种情况时显示特定应用程序的ANR对话框:
在5秒内无法响应输入事件(例如按键或屏幕触摸事件)。
BroadcastReceiver尚未在10秒内完成执行。
所以,答案是否定的。如果要避免ANR,从主线程访问SQLite虚拟表是不安全的。您可以使用AsyncTasks访问您的数据库。
从评论中更新:
尽管从SQLite的角度来看整个表都在内存中,但是从Android的角度来看,系统需要访问数据库并且它可能导致性能问题,例如,如果表足够大,或者取决于实现,
因为它们可以长时间运行,所以请确保在后台线程中调用getWritableDatabase()或getReadableDatabase(),例如使用AsyncTask或IntentService
(来自Saving Data in SQL Databases)
@Chebyr正在使用一个包含5000行和15个String列的表,这些列通过5个游标的连接形成,作为内存缓存,用于快速访问,为过滤操作编制索引。因此,假设字符串长度为7个字符,它将大约为500KB,而不是非常消耗内存(取决于索引解决方案的实现),我不希望使用索引访问它非常耗时。如果数据是静态的,我会尝试使用@Chebyr提出的解决方案之一并测量时间和内存(我刚刚使用普通的Java示例测试了CQEngine并且看起来很有希望)。
此外,Best practice for keeping data in memory and database at same time on Android可能会有所帮助。