1

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:

https://code.google.com/archive/p/multiindexcontainer/

https://github.com/npgall/cqengine

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Chebyr
  • 2,171
  • 1
  • 20
  • 30

1 Answers1

1

From The Virtual Table Mechanism Of SQLite:

From the perspective of an SQL statement, the virtual table object looks like any other table or view.

But behind the scenes, queries and updates on a virtual table invoke callback methods of the virtual table object instead of reading and writing to the database file.

So, from the Android perspective, SQLite Virtual tables behave exactly as any other table or view, and according to the documentation about ANRs:

(...)

In any situation in which your app performs a potentially lengthy operation, you should not perform the work on the UI thread, but instead create a worker thread and do most of the work there. This keeps the UI thread (which drives the user interface event loop) running and prevents the system from concluding that your code has frozen. Because such threading usually is accomplished at the class level, you can think of responsiveness as a class problem. (Compare this with basic code performance, which is a method-level concern.)

In Android, application responsiveness is monitored by the Activity Manager and Window Manager system services. Android will display the ANR dialog for a particular application when it detects one of the following conditions:

  • No response to an input event (such as key press or screen touch events) within 5 seconds.

  • A BroadcastReceiver hasn't finished executing within 10 seconds.

So, the answer is no. It's not safe to access a SQLite virtual table from main thread if you want to avoid ANRs. You can use AsyncTasks to access your database.

Update from the comments:

Although the entire table is in memory from the SQLite perspective, from the Android perspective the system needs to access a database and it can cause performance issues for example if the table is large enough, or depending on the implementation,

Because they can be long-running, be sure that you call getWritableDatabase() or getReadableDatabase() in a background thread, such as with AsyncTask or IntentService

(from Saving Data in SQL Databases)

@Chebyr is using a table of 5000 rows and 15 String columns formed through join of 5 cursors to act as an in memory cache for fast access, indexed for filtering operations. So, assuming that the strings are 7 characters long medium, it would be about 500KB, not very memory consuming (depending on the implementation of the indexed solution) and I would not expect to be very time consuming accessing it using indexes. If the data is static I would try using one of the solutions @Chebyr proposed and measuring time and memory (I have just tested CQEngine using a plain Java example and looks very promising).

Also, Best practice for keeping data in memory and database at same time on Android can be helpful.

Community
  • 1
  • 1
antonio
  • 18,044
  • 4
  • 45
  • 61
  • Since there is no real disk access and the entire table is in memory, what would cause a potentially lengthy operation? – Chebyr Apr 07 '16 at 11:28
  • The entire table is in memory from the SQLite perspective, but from the Android perspective the system needs to access a database. For example if the table is large enough it can cause lengthy operations. Also, depending on your implementation, _Because they can be long-running, be sure that you call getWritableDatabase() or getReadableDatabase() in a background thread, such as with AsyncTask or IntentService_ (from http://developer.android.com/intl/es/training/basics/data-storage/databases.html) – antonio Apr 07 '16 at 11:33
  • That answers the first part of the question. So what alternative code pattern do you suggest for a data table of string columns with full text searching enabled for all the columns? – Chebyr Apr 07 '16 at 12:14
  • I suggest (the last sentence of my answer, please tell me if you need me to elaborate it a bit more) to use an `AsyncTask` to perform database related operation on background and publish results on the UI thread (http://developer.android.com/intl/es/reference/android/os/AsyncTask.html) – antonio Apr 07 '16 at 12:17
  • I meant what alternative to SQLite virtual table do you suggest as a data structure to be used on main thread with full text search support? – Chebyr Apr 07 '16 at 12:25
  • A solution like the ones you are proposing are valid to query in-memory data, but why do you need to query your data on the main thread? What is the expected size of your data? – antonio Apr 07 '16 at 13:17
  • A table of 5000 rows and 15 String columns formed through join of 5 cursors to act as an in memory cache for fast access. Indexed for filtering operations. – Chebyr Apr 07 '16 at 13:48
  • Assuming that your strings are 7 characters long medium, it would be about 500KB, not very memory consuming (depending on the implementation of the indexed solution) and I would not expect to be very time consuming accessing it using indexes. If your data is static I would try using one of the solutions you propose and measuring time and memory (I have just tested CQEngine using a plain Java example and looks very promising). Also this answer can be helpful: http://stackoverflow.com/questions/3679664/android-best-practice-for-keeping-data-in-memory-and-database-at-same-time – antonio Apr 07 '16 at 14:53
  • Thanks for your help. Please update your answer to reflect the content of our discussion so that I can mark it as the accepted answer. – Chebyr Apr 07 '16 at 15:55
  • Glad to help :) I have edited my answer to reflect our comments – antonio Apr 07 '16 at 16:12