Wann und wie setze ich eine Datenbank (Room) im Lifecycle der App ein?

  • 8 Antworten
  • Letztes Antwortdatum
L

LIronLeaves

Neues Mitglied
0
Hi,
ich bin ein Hardwaredesigner und kam vor zwei Monaten auf die Super-Idee, meine Hardware mit einer App anzusteuern und das selbst zu programmieren. Ich bin also ein absoluter Neuling in Android App Design und habe gerade ein Verständnisproblem bezüglich dem Einsatz von Datenbanken in einer App. Ich hoffe, das Forum kann helfen. Mir ist klar wozu eine Datenbank dient, wie das mit den Tabellen funktioniert, was Schemata sind, Queries usw. Mir ist in groben Zügen klar, wie ich die Datenbank (ich nehme Room) aufsetze, dh. DAO, Entity usw. leuchten mir ein.

Aber: Ich verstehe nicht, wie ich eine Datenbank mit default Werten erstelle bzw. wann im Lifecycle ich das tue.

Als Beispiel: Ich habe eine App, die wird mit einer Datenbank ausgeliefert. Die Datenbank soll default-Werte enthalten. Nehmen wir als Primärschlüssel eine Stadt, als Einträge ein Gebäude und ein Bild vom Gebäude: Kuala Lumpur;Petronas Towers;Bild der Towers.
Ich weiß: Es gibt die Methode createFromAsset(). Das heißt, die Datenbank als solche wird z.B. in onCreate() einer Activity erstellt, indem hier die Methode createFromAsset()gerufen wird. Ist das korrekt? Wenn ja, dann müssen die Daten im Asset Ordner meines Projekts liegen. (createFromFile finde ich persönlich bezüglich der Sicherheit schwierig, aber das geht natürlich auch, führt aber zu den gleichen Fragen)

Aber in welcher Form liegen sie da? Schon als Tabelle in Art eines CSV? Was ist mit Bildern (ich muss mit der App offline arbeiten...)? Wie werden die im Asset abgelegt und mit der Tabellendefinition verknüpft? Ich habe schon viel gesucht, aber kenn jemand ein Tutorial für pre-populated Room / vorausgefüllte Room Datenbank?

Vielen Dank für Eure Hilfe!
 
Hallo @LIronLeaves

herzlichst willkommen im Forum.

Ich würde eine CSV in den Assets mitliefern und einmalig zur Runtime eine Sqlite DB erstellen.
Wobei ich Diese im internen Cache anstatt als File führen würde.

Als "Done" Flag dann mit SharedPrefernces arbeiten.
Kleiner Hinweis : Beim einmaligen Befüllen dann mit Threads arbeiten.

Verweis auf Image Dateien : auch einen Tabelleneintrag mit Verweis auf die Assets, oder direkt auf die Resourcen ID
(je nachdem, wo du sie hinterlegt haben möchtest und welche DPI sie besitzen)
Bei Verwendung dann das ImageView füllen - oder recht intelligente Libraries wie z.b. Glide verwenden.
Man sollte bei Image Operationen auf den internen Speicher achten .
 
Zuletzt bearbeitet:
Hallo und Willkommen im Forum

Du willst ein ausgefüllte DB der APK mitgeben.

Sinnvoll ist es die DB in den Asset im Projekt zu speichern und so der APK mitzugeben.
Problem bei der Sache ist das du aus denn Assets nur lesen und nicht schreiben kannst.
Also ein öffnen den der DB Datei aus denn Assets ist nicht gut.
Du musst die DB beim ersten App Start in dein App Verzeichnis kopieren, erst dann kannst du die DB öffnen und damit arbeiten.

Dein createFromAsset() wird dir da nicht viel bringen.
Das heißt, die Datenbank als solche wird z.B. in onCreate() einer Activity erstellt, indem hier die Methode createFromAsset()gerufen wird. Ist das korrekt?
nein
Mit CreateFromAsset erstellt du keine DB. Damit kannst du Daten aus den Assetts lesen und diese dann in deine über den DBHelper erstellte DB, Tabelle einfügen.


Auch werden die daten nicht in einer CSV Datei gespeichert. Du erstellst die DB auf deinem Handy füllst sie schon mal aus und speicherst sie. Dann kopierst du die DB Datei aus dem App Ordner in ein anderes Verzeichnis was du vom PC aus sehen kannst. Das geht aber nur auf einem gerooteten Handy.

Diese Datei packst du in dein Projekt in den Asset Ordner.

Android - Create Database from assets folder | android Tutorial
 
Zuletzt bearbeitet:
Aha!
@swa00 und @jogimuc, vielen Dank für Eure Antworten. Jetzt wird mir einiges klarer, besonders, dass ich unbedingt das Tutorial machen muss ;-)

Ich hatte im Kopf, eine fertiggestellte Tabelle mitzuliefern, fand das dann aber aus zwei Gründen unpraktisch: erstens muss ich diese vorab erstellen, wobei ich wahrscheinlich ein extra Tool benötige, sofern android studio für diesen Fall nichts mitliefert. Aber letztendlich kann ich damit gut leben.
Zweitens möchte ich sicherstellen, dass die Datenbank nicht aus Versehen durch den User korrumpiert, gelöscht etc. werden kann. Ich möchte die Möglichkeit haben, mittels "Preset" die Original Datenbank wieder herzustellen, sollte es nötig sein und dem user soll es nicht möglich sein, die Originaldaten zu ändern sondern nur jene, die er selbst hinzugefügt hat. Indem ich nur die Daten mitliefere aber nicht die DB und diese dann zur Runtime intern aufbaue, kann ich die DB ruinieren, aber nicht die Daten (read only). Ich hoffe, mein Ansatz ist verständlich...

Wie wird in der Praxis dieser Fall abgefangen? Ich werde ja nicht der erste sein, der solche Anforderungen stellt...Wird die Stammdatenbank bei der ersten Ausführung kopiert und dann ausschließlich auf der Kopie gearbeitet? Wenn dem so ist, wie ist das mit dem Speicher, wenn ich zwei Datenbanken ablegen muss? Ab wann ist es sinnvoll, doch online zu arbeiten, also die Daten von einem Server zur Runtime zu holen?
 
Hallo @LIronLeaves ,

so ganz versteh ich dein Problem nicht :)

a) Du lieferst in den Assets eine CSV mit.
b) Beim Erststart der App erstellst du die DB aus der CSV
c) Wenn du einen Reset benötigst - Tabelle(n) in der DB löschen und erneut einspulen - fertig
 
Hallo
Ja so ganz kann ich auch nicht nachvollziehen wo das Problem ist.

Also erstmal die mitgelieferte CSV Datei ist nicht deine Tabelle in der DB.
Zu Punkt A muss ich sagen dass du nicht mit der CSV Datei deine DB und Tabelle erstellt.
Kann sein das dies Room kann, und wenn ja werden genau hier deine verständigungs- Probleme anfangen.
Du hast eine DB und in der ist eine Tabelle das ist nicht die CSV.

Sondern selber die DB und Tabelle mit den Methoden des SQLHelper erstellen würdest, wüstest du das.
Richtig beim ersten App Start liest du die CSV Datei Zeilenweise ein und füllst somit deine Tabelle in der DB. Erstellt also neue DatenSätze in deine DB Tabelle.
Da Room dir das wohl alles abnimmt scheint dir hier etwas der Zusammen hang zu fehlen.


Da die Tabelle zuvor noch lehr war sind das die ersten Datensätze und auch IDs.
Wenn also der User was löschen verändern will kannst du prüden ob es einer der ersten IDs ist und somit das löschen , ändern verhindern in der Methode die du dafür erstellt hast.

Auch kannst du das mit SQL Tirgger über die DB machen.
Auch eine Möglichkeit in der DB Tabelle ein Flag zu benutzen was bei Einlesen aus der CSV für jeden Datensatz gesetzt wird. Wenn der User was eingibt wird es nicht gesetzt.
Dieses Flag kannst du ja auch schon in der CSV mit führen.

Somit hast du eine einfache Unterscheidung der Daten.
Auch kannst du auf das Flag einen SQL Trigger setzen.


c) Wenn du einen Reset benötigst - Tabelle(n) in der DB löschen und erneut einspulen – fertig

Das will er ja eigentlich nicht, er will ja nur die mitgelieferten Daten die der User verändert neu einlesen, aber die Daten des Users erhalten.
Deshalb Daten Schützen vor Veränderung. Flag , Trigger eigenes überprüfen in der ändern oder löschen Methode.

Wird die Stammdatenbank bei der ersten Ausführung kopiert und dann ausschließlich auf der Kopie gearbeitet?
Wenn dem so ist, wie ist das mit dem Speicher, wenn ich zwei Datenbanken ablegen muss?

Es wir eine Datenbank erstellt und in dieser wird eine Tabelle erstellt. (es können auch mehrere Tabelle in einer DB sei die sogar in Beziehung stehen)
Mit Hilfe der CSV Datei speicherst du deine ersten Datensätze in die Tabelle der DB. Das ist genau so ein Import wie es später der User macht. Hast du zb 10 Zeilen in deinem CSV wird 10 mal Import gemacht und die Daten hinzugefügt Kopiert wird da nichts.

Wieso brauchst du Zwei Datenbanken? Eine zweite Tabelle ja.

Maximale Größe einer Datenbank! SQLite auf einem Android-System
Größe einer Sqlite Datenbank in bytes
 
Zuletzt bearbeitet:
@jogimuc
Das will er ja eigentlich nicht, er will ja nur die mitgelieferten Daten die der User verändert neu einlesen, aber die Daten des Users erhalten.

Schreibt er aber ...
Ich möchte die Möglichkeit haben, mittels "Preset" die Original Datenbank wieder herzustellen, sollte es nötig sein und dem user soll es nicht möglich sein, die Originaldaten zu ändern sondern nur jene, die er selbst hinzugefügt hat.

Ich sprach auch nur von der Tabelle, nicht von der kompletten DB ..
Ich erstelle z.b. einen DB-View über mehrere Tabellen

@LIronLeaves
Du führst am besten zwei Tabellen - die Originale und die des Users.
Einen Select führst du über einen DB-View über beide Tabellen aus.
Und solltest du einen Reset über die originalen Datensätze benötigen, machst du das auch nur in der entsprechenden Tabelle

Hier was zum Lesen :
SQLite Create View: Learn How to Create View in SQLite
 
Zuletzt bearbeitet:
Hola,

endlich wieder Zeit für das Forum... :)
Vielen Dank für die vielen Hinweise und Tipps. Und ja - ich bin HF-Analogtechniker der C für µC gelernt hat und sich jetzt an Android und Kotlin versucht. Ich glaube deshalb drücke ich mich nicht präzise genug aus oder verstehe die Antworten noch teilweise falsch. Wie auch immer, erstmal herzlichen Dank @swa00 und @jogimuc !!!

Zur Datenbank: Ich habe verstanden, dass ein CSV nicht die Datenbank und nicht die Tabelle sind. Die CSV erschien mir als geeigneter Container für meine Stammdaten, um diese in die App zu importieren, ohne die Daten hart zu codieren. Bei Bedarf tausche ich das CSV aber muss den Code nicht anfassen. Soweit (Einlesen, checken, formatieren, ablegen usw.) bin bis heute gekommen. Aber:

Jogimuc hat völlig richtig bemerkt, dass ich mich noch nicht mit der DB wirklich auseinander gesetzt habe (hach, der Alltag), was ich jetzt aber mal angehen möchte. Meine eigentliche Frage war ja, wie ich die DB mit Stammdaten fülle und wann im Lifecycle ich das tue. Der Input hier hat diese Frage beantwortet, auch wenn ich die Antworten erstmal verdauen muss... Ich hänge mich jetzt also an die Tutorials und Tasten und würde sagen: Bis Bald! :)
 
Danke für dein Feedback.

Viel Erfolg
 
Zurück
Oben Unten