Biblioteca Qt C ++ en Android Proyecto Eclipse: controlador QSQLITE no cargado
He creado una lib Qt dinámica que utiliza Qt SQL para abrir una base de datos SQLite, pero estoy recibiendo este error:
QSqlDatabase: QSQLITE driver not loaded QSqlDatabase: available drivers:
El DLL estaba funcionando bien como parte de una aplicación Qt Android, sin embargo necesito usarlo a través de JNI desde una aplicación Java existente desarrollada en Eclipse.
- Comparación entre QAbstractButton y QPushButton * carece de un molde
- Qt Haptic Comentarios sobre android
- Animar nuevos elementos en un TableView
- ¿Está QT disponible para plataformas Android y iPhone?
- Convertir jstring a QString
Este es el código de ejemplo más corto que reproduce el problema. Cargo la biblioteca de Java y llamo su método de init()
:
System.loadLibrary("plugins_sqldrivers_libqsqlite"); System.loadLibrary("Qt5Sql"); System.loadLibrary("MyQtLib"); MyQtLib.init();
Y dentro de la biblioteca de Qt acabo de llamar a 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"); }
Dado que el error es QSQLITE driver not loaded
, y la biblioteca Qt estaba trabajando dentro de una aplicación Qt, supongo que Qt está haciendo alguna inicialización que me falta.
Pero esto no quita el error, así que debe ser algo más. Normalmente, la aplicación Qt utilizará QtApplication.java y QtActivity.java para realizar alguna inicialización, por lo que deben estar haciendo algo más allí que no estoy haciendo.
- Ejecutar un comando shell a través de QProcess en la plataforma Android
- Qml Cómo usar loader dentro de tabview
- Qt android, la nueva ventana qml no funciona correctamente
- ¿Cómo puedo cambiar la plataforma --android en Qt Creator para no ser android - 1 en el modo de depuración?
- La ventana principal no recibe eventos después de cerrar el diálogo modal
- QGuiApplication detiene el bucle de eventos cuando el teléfono está bloqueado cuando se compila con Qt 5.3 o Qt 5.4 (pero no con Qt 5.2)
- Qt para Android - el equivalente de startActivityForResult no funciona
- Qt Android: Al presionar "Hecho" no oculta el teclado
Eventualmente me puse en las fuentes Qt para ver cómo se carga el complemento SQLITE (por lo menos para el escritorio).
La función relevante fue QFactoryLoader :: update () . En él me di cuenta de que itera todos los directorios en QCoreApplication::libraryPaths()
:
QStringList paths = QCoreApplication::libraryPaths(); for (int i = 0; i < paths.count(); ++i) {
Si alguno de ellos tiene un subdirectorio llamado "sqldrivers", va dentro de él e intenta cargar todas las bibliotecas dinámicas en ese subdirectorio.
A continuación, qDebug() << a.libraryPaths();
los caminos de la biblioteca en un proyecto de prueba que corría directamente desde Qt Creator – qDebug() << a.libraryPaths();
, Y vi esta ruta – /data/data/org.qtproject.example.untitled/qt-reserved-files/plugins
. En este directorio en mi teléfono android había un subdirectorio llamado sqldrivers
, que contenía un solo archivo – libqsqlite.so
.
Entonces comprobé los archivos de .java, y de hecho QtActivity::startApp()
agrega la trayectoria de la biblioteca:
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; }
La solución entonces sería asegurarse de que hay un sqldrivers/libqsqlite.so
algún lugar del teléfono, y luego agregar la carpeta primaria de sqldrivers
a la ruta de la biblioteca usando QCoreApplication::addLibraryPath()
.