Skip to content


Subversion checkout URL

You can clone with
Download ZIP


TouchDB does not work on Android 4.1 #48

mschoch opened this Issue · 12 comments

6 participants


java.lang.NoSuchFieldError: no field with name='mNativeHandle' signature='I' in class Landroid/database/sqlite/SQLiteDatabase;
at com.couchbase.touchdb.TDCollateJSON.nativeRegisterCustomCollators(Native Method)
at com.couchbase.touchdb.TDCollateJSON.registerCustomCollators(
at com.couchbase.touchdb.TDDatabase.createEmptyDBAtPath(
at com.couchbase.touchdb.testapp.tests.CRUDOperations.testCRUDOperations(
at java.lang.reflect.Method.invokeNative(Native Method)
at android.test.AndroidTestRunner.runTest(
at android.test.AndroidTestRunner.runTest(
at android.test.InstrumentationTestRunner.onStart(


TouchDB relies on some low-level implementation details to manually install our own collators using native code. On the surface it looks like those low-level details changed and broke our implementation. Unfortunately, source code for Android 4.1 is not available yet, making it hard to diagnose further.


Damn, running into this too.

I'ts kind of important for us to be able to deploy on 4.1 - can you maybe give an estimation when you'll be able to work on this one?


maybe time to move the whole thing to H2 anyways, see here and here


I've put in a fix that works in some cases (not convinced it works in all cases because of the way Android changed things)


The unit tests pass and AndroidGrocerySync works as expected in the 4.1 emulator now, so its clearly an improvement worth sharing.


Could you elaborate on where you think we might run into trouble with this fix? Does it seem that the new hook may be device-dependent?


The issue is that SQLiteDatabase no longer has a 1-1 mapping to the underlying sqlite handle (at the c library layer). Ideally, whenever a new sqlite handle is opened, we need to register our custom collation functions there. Now, SQLiteDatabase has a ThreadLocal reference to a SQLiteSession, which has reference to a SQLiteConnectionPool which has a pool of SQLiteConnections's. Each of these has their own sqlite handle (at the c library layer).

All of this means its a lot harder (maybe impossible) to reliably ensure our custom collation functions are always registered. I coded up what we needed to make sure it gets registered on the "primary" connection, which is the one that it uses when you first call openDatabase().

I actually didn't expect AndroidGrocerySync to work with this patch because I was pretty sure we have multiple threads accessing the SQLiteDatabase (in a coordinated manner). But, for some reason it does work. I have not had the time to go back and get a better understanding of why this is.


I think you're taking the wrong approach here. Both native code and custom collators were KISS violations anyway and now this mess. So instead of registering a custom collator, compute an artificial collation key from the JSON that is e.g. a string and that has the quality that a comparison on that string with the built-in collator matches comparison on the corresponding JSON. Then store that key in the key column of your table. If you look at java.text.spi.CollatorProvider that comes with Open/Sun JDK (not Android) then you see it does the same thing (computing an artificial key) for performance reasons, only it is a binary blob.


Thanks for the input, can you point me to any sample code doing this?


Sorry no. I had the artificial collation key mostly figured out in my mind when I did the research into porting TouchDB to H2/JDBC but I'd yet have to type it in.


Maybe it is better to include SQLite code in TouchDB? That way TouchDB is independent from the underneath changes?

@tleyden tleyden was assigned
@tleyden tleyden closed this

I've been testing extensively on Android 4.2 with no observed issues. Just now tried 4.1 and didn't see any problems.

@yaronyg yaronyg referenced this issue from a commit in thaliproject/couchbase-lite-android
@mschoch mschoch fixed support for Android 4.1 (in some cases)
not convinced this works in all cases, but unit tests pass
and AndroidGrocerySync works, so better than nothing

@mschoch mschoch referenced this issue in couchbase/couchbase-lite-android

Error creating database on L Developer Preview #373

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.