Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: Datenbanken ::  SQLite in Android-Service     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
Skylac06
Mitglied

Benutzerprofil
Anmeldungsdatum: 13.02.2017
Beiträge: 82
Beitrag Skylac06 Mitglied 18:10:44 30.07.2017   Titel:   SQLite in Android-Service            Zitieren

Hallo,

ich habe eine Datenbank, auf die ich über Qt zugreife, und eine C++-Funktion, in der auf die Datenbank zugegriffen wird. Die Funktion funktioniert auch einwandfrei, wenn ich sie von C++ aus aufrufe.
Nur wenn ich sie von Java aus mit einem beim Boot gestarteten Service aufrufe, lässt sich die Datenbank nicht öffnen, weil der SQLite-Treiber nicht geladen wurde. Der Funktionsaufruf an sich funktioniert auch, ich bekomme nur meine eigenen Debug-Meldungen, dass sich die Datenbank nicht öffnen ließ.
Die QSQLite-Library ist aber in dem Verzeichnis "/data/data/my.app.package.MyApp/qt-reserved-files/plugins/sqldrivers/libqsqlite.so".
Ich habe nun also einmal in der Java-Datei Folgendes hinzugefügt:
Java:
    static {
        System.loadLibrary("MyAppLib");
        System.loadLibrary("qsqlite");    // Service-Absturz
    }

Die libMyAppLib.so brauche ich für den Funktionsaufruf. Das funktioniert auch.
Nur der Aufruf System.loadLibrary("qsqlite"); führt zu einem Service-Absturz.
Testweise habe ich es auch einmal mit System.loadLibrary("sqlite"); versucht, das führte aber zu keinem Absturz und auch keiner Fehlermeldung in der Log-Datei, nur meine Debug-Meldungen erscheinen, dass die Datenbank nicht geöffnet werden konnte und das an nicht geladenen Treibern liegt.
Wie gesagt, wenn ich aber die App öffne (nicht den Service; der startet ja direkt nach dem Boot) kann die Datenbank über die gleiche Funktion gelesen werden.

Vielen Dank schon einmal für eure Hilfe!
Skylac06
Mitglied

Benutzerprofil
Anmeldungsdatum: 13.02.2017
Beiträge: 82
Beitrag Skylac06 Mitglied 19:23:52 30.07.2017   Titel:              Zitieren

Ich habe nun einmal libqsqlite.so direkt in "/path/to/build/android-build/libs/x86/" eingefügt, das .apk-Archiv neu erstellt und schon stürzt der Service nicht mehr ab. In "/data/data/my.app.package.MyApp/qt-reserved-files/plugins/sqldrivers/" scheint Java die nicht zu finden.
Dennoch kann ich immer noch nicht die Datenbank öffnen - weiterhin ist der Treiber wohl nicht geladen worden.

Hat noch jemand eine Idee?

Edit:
Durch den QtCreator wird die libsqlite.so anscheinend nur in libplugin_sqldrivers_libqsqlite.so umbenannt. System.loadLibrary("plugin_sqldrivers_libqsqlite"); funktioniert also.
Allerdings wird auch so nichts geladen.
Kann man die Treiber irgendwie manuell laden?

Edit Nr. 2:
Ich vermute, dass die Libraries nicht geladen werden können, weil es keine QCoreApplication gibt und die LibraryPaths deshalb nicht definiert sind.
Wenn ich die aber über einen QPluginLoader mit einer absoluten Pfadangabe lade, kann ich die Datenbank immer noch nicht öffnen.

Edit Nr. 3:
Auch wenn das vermutlich eher eine Qt-Frage ist: kann man QCoreApplication irgendwie initialisieren ohne die Schleife (QCoreApplication::exec()) auszuführen? Damit eben die ganzen Pfade wie ApplicationDirPath, ApplicationFilePath und LibraryPath bereits gesetzt sind?

Inzwischen, wenn ich mit QCoreApplication::addLibrary("/data/data/my.app.package.MyApp/qt-reserved-files/plugins"); und QCoreApplication::addLibrary("/data/app/my.app.package.MyApp/lib/architecture" die Pfade hinzufüge, kann ich die Datenbank öffnen. Es kann aber keine Abfrage ausgeführt werden, weil angeblich kein Treiber geladen ist. Wenn ich mir aber QSqlDatabase::drivers() ausgebe, habe ich eindeutig den Treiber geladen.
Den Pfad der Datenbank musste ich natürlich auch absolut angeben, weil kein QCoreApplicationFilePath gesetzt ist. Das sind aber eigentlich keine schönen und dauerhaften Lösungen, weshalb es vermutlich das Beste wäre, wenn ich eine QCoreApplication verwende. Kann ich die sonst nicht auch in Java irgendwie initialisieren?

Edit Nr. 4:
Ich musste das alte QSqlQuery-Objekt löschen und ein neues erstellen, damit die Verbindung aktualisiert wird. Es sieht jetzt verkürzt so aus:

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Controller::Controller(QString databaseName, QObject *parent) : QObject(parent), db(QSqlDatabase::addDatabase("QSQLITE")), query(new QSqlQuery(db))
{
    if(!QSqlDatabase::drivers().contains(db.driverName()))
    {
        QCoreApplication::addLibraryPath("/data/data/my.app.package/qt-reserved-files/plugins/");
        QCoreApplication::addLibraryPath("/data/app/my.app.package-1/lib/x86");
 
        QSqlDatabase::removeDatabase(QSqlDatabase::defaultConnection);
        delete query;
        db = QSqlDatabase::addDatabase("QSQLITE");
        query = new QSqlQuery(db);
    }
    db.setDatabaseName(QString("/data/data/my.app.package/files/") + databaseName);
}


Das ist aber natürlich mit den ganzen absoluten Pfadangaben sehr unschön, auch wenn es funktioniert (aber auch nicht sichergestellt, dass es immer funktioniert).
Wie bestimmt denn eigentlich QCoreApplication die ganzen Pfade? Kann ich das nicht ansonsten selbst machen?


Zuletzt bearbeitet von Skylac06 am 13:29:15 31.07.2017, insgesamt 4-mal bearbeitet
C++ Forum :: Datenbanken ::  SQLite in Android-Service   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.