Qt C ++ library in Android Eclipse project: QSQLITE driver not loaded

I created a dynamic Qt library that uses Qt SQL to open a SQLite database, but I get this error:

QSqlDatabase: QSQLITE driver not loaded QSqlDatabase: available drivers: 

The DLL works fine as part of the Qt application for Android, however I need to use it through JNI from an existing Java application developed in Eclipse.

This is the shortest code example that reproduces the problem. I load the library from Java and call its init() method:

 System.loadLibrary("plugins_sqldrivers_libqsqlite"); System.loadLibrary("Qt5Sql"); System.loadLibrary("MyQtLib"); MyQtLib.init(); 

And inside the Qt library, I just call QSqlDatabase :: addDatabase ():

 JNIEXPORT void JNICALL Java_test_MyQtLib_foo(JNIEnv *, jclass) { // Manually create a QCoreApplication instance. int argc = 1; static char arg[] = ""; static char *arg2 = arg; app = new QCoreApplication(argc, &arg2); // Try to add an SQLite db connection. QSqlDatabase::addDatabase("QSQLITE"); } 

Since the QSQLITE driver not loaded error is QSQLITE driver not loaded , and the Qt library works inside the Qt application, I assume that Qt does some initialization, which I am missing.

But this did not fix the error, so there must be something else. Typically, a Qt application will use QtApplication.java and QtActivity.java to do some initialization, so they should do something else that I do not.

+7
c ++ android eclipse qt
source share
1 answer

In the end, I went into Qt sources to find out how the SQLITE plugin loads (at least for building the desktop).

The corresponding function was QFactoryLoader :: update () . In it, I noticed that it QCoreApplication::libraryPaths() through all the directories in QCoreApplication::libraryPaths() :

 QStringList paths = QCoreApplication::libraryPaths(); for (int i = 0; i < paths.count(); ++i) { 

If any of them has a subdirectory named "sqldrivers", it goes into it and tries to load all the dynamic libraries in this subdirectory.

Then I printed the library paths in a test project that I ran directly from Qt Creator - qDebug() << a.libraryPaths(); and I saw this way - /data/data/org.qtproject.example.untitled/qt-reserved-files/plugins . In this directory on my Android phone there was a subdirectory named sqldrivers that contained one file - libqsqlite.so .

Then I checked the .java files, and indeed QtActivity::startApp() adds the library path:

 boolean bundlingQtLibs = false; if (m_activityInfo.metaData.containsKey("android.app.bundle_local_qt_libs") && m_activityInfo.metaData.getInt("android.app.bundle_local_qt_libs") == 1) { localPrefix = getApplicationInfo().dataDir + "/"; pluginsPrefix = localPrefix + "qt-reserved-files/"; cleanOldCacheIfNecessary(localPrefix, pluginsPrefix); extractBundledPluginsAndImports(pluginsPrefix); bundlingQtLibs = true; } 

Then the solution would be to ensure that the phone has sqldrivers/libqsqlite.so , and then add the parent sqldrivers folder to the library path using QCoreApplication::addLibraryPath() .

+4
source share

All Articles