1004 Stimmen

Lieferung einer Anwendung mit einer Datenbank

Wenn für Ihre Anwendung eine Datenbank erforderlich ist und diese bereits über integrierte Daten verfügt, wie kann ich diese Anwendung am besten ausliefern? Sollte ich:

  1. Erstellen Sie die SQLite-Datenbank vor und fügen Sie sie in die Datei .apk ?

  2. Die SQL-Befehle in die Anwendung einbinden und dafür sorgen, dass die Datenbank erstellt und die Daten bei der ersten Verwendung eingefügt werden?

Die Nachteile, die ich sehe, sind:

  1. Mögliche SQLite-Versionsunterschiede könnten Probleme verursachen, und ich weiß derzeit nicht, wo die Datenbank gespeichert werden soll und wie man auf sie zugreift.

  2. Es kann sehr lange dauern, bis die Datenbank auf dem Gerät erstellt und aufgefüllt ist.

Irgendwelche Vorschläge? Für Hinweise auf die Dokumentation zu etwaigen Problemen wären wir Ihnen sehr dankbar.

3voto

gorefest Punkte 809

Android bietet bereits ein versionsorientiertes Konzept für die Datenbankverwaltung. Dieser Ansatz wurde im BARACUS-Framework für Android-Anwendungen wirksam eingesetzt.

Es ermöglicht Ihnen, die Datenbank über den gesamten Versionslebenszyklus einer Anwendung zu verwalten, indem Sie die Sqlite-Datenbank von einer früheren Version auf die aktuelle aktualisieren können.

Außerdem können Sie Hot-Backups und Hot-Recovery von SQLite durchführen.

Ich bin mir nicht 100%ig sicher, aber eine Hot-Recovery für eine spezifisch Gerät kann es Ihnen ermöglichen, eine vorbereitete Datenbank in Ihrer Anwendung zu verwenden. Aber ich bin mir nicht sicher über das Binärformat der Datenbank, das für bestimmte Geräte, Hersteller oder Gerätegenerationen spezifisch sein könnte.

Da das Material unter der Apache License 2 steht, können Sie jeden Teil des Codes wiederverwenden, die auf github gefunden werden kann

EDIT :

Wenn Sie nur Daten ausliefern wollen, sollten Sie in Erwägung ziehen, POJOs beim ersten Start der Anwendung zu instanziieren und zu persistieren. BARACUS hat dafür eine eingebaute Unterstützung (Eingebauter Schlüsselwertspeicher für Konfigurationsinformationen, z.B. "APP_FIRST_RUN" plus einen After-Context-Bootstrap-Hook, um Post-Launch-Operationen auf dem Kontext auszuführen). Dies ermöglicht es Ihnen, eng gekoppelte Daten mit Ihrer App auszuliefern; in den meisten Fällen passte dies zu meinen Anwendungsfällen.

3voto

Ilya Gazman Punkte 29734

Ich schrieb eine Bibliothek um diesen Prozess zu vereinfachen.

dataBase = new DataBase.Builder(context, "myDb").
//        setAssetsPath(). // default "databases"
//        setDatabaseErrorHandler().
//        setCursorFactory().
//        setUpgradeCallback()
//        setVersion(). // default 1
build();

Es wird eine Datenbank aus assets/databases/myDb.db Datei. Darüber hinaus erhalten Sie alle diese Funktionen:

  • Datenbank aus Datei laden
  • Synchronisierter Zugriff auf die Datenbank
  • Verwendung von sqlite-Android durch Abfrage, Android-spezifische Verteilung der neuesten Versionen von SQLite.

Klonen Sie es von github .

2voto

Jaco Punkte 249

Wenn die benötigten Daten nicht zu groß sind (die Grenzen sind mir nicht bekannt, sie hängen von vielen Dingen ab), können Sie die Daten auch von einer Website/Webapp herunterladen (in XML, JSON oder sonst wie). Nach dem Empfang führen Sie die SQL-Anweisungen unter Verwendung der empfangenen Daten aus, erstellen Ihre Tabellen und fügen die Daten ein.

Wenn Ihre mobile Anwendung viele Daten enthält, kann es später einfacher sein, die Daten in den installierten Anwendungen mit genaueren Daten oder Änderungen zu aktualisieren.

2voto

Ich verwende ORMLite und der folgende Code hat bei mir funktioniert

public class DatabaseProvider extends OrmLiteSqliteOpenHelper {
    private static final String DatabaseName = "DatabaseName";
    private static final int DatabaseVersion = 1;
    private final Context ProvidedContext;

    public DatabaseProvider(Context context) {
        super(context, DatabaseName, null, DatabaseVersion);
        this.ProvidedContext= context;
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        boolean databaseCopied = preferences.getBoolean("DatabaseCopied", false);
        if (databaseCopied) {
            //Do Nothing
        } else {
            CopyDatabase();
            SharedPreferences.Editor editor = preferences.edit();
            editor.putBoolean("DatabaseCopied", true);
            editor.commit();
        }
    }

    private String DatabasePath() {
        return "/data/data/" + ProvidedContext.getPackageName() + "/databases/";
    }

    private void CopyDatabase() {
        try {
            CopyDatabaseInternal();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private File ExtractAssetsZip(String zipFileName) {
        InputStream inputStream;
        ZipInputStream zipInputStream;
        File tempFolder;
        do {
            tempFolder = null;
            tempFolder = new File(ProvidedContext.getCacheDir() + "/extracted-" + System.currentTimeMillis() + "/");
        } while (tempFolder.exists());

        tempFolder.mkdirs();

        try {
            String filename;
            inputStream = ProvidedContext.getAssets().open(zipFileName);
            zipInputStream = new ZipInputStream(new BufferedInputStream(inputStream));
            ZipEntry zipEntry;
            byte[] buffer = new byte[1024];
            int count;

            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                filename = zipEntry.getName();
                if (zipEntry.isDirectory()) {
                    File fmd = new File(tempFolder.getAbsolutePath() + "/" + filename);
                    fmd.mkdirs();
                    continue;
                }

                FileOutputStream fileOutputStream = new FileOutputStream(tempFolder.getAbsolutePath() + "/" + filename);
                while ((count = zipInputStream.read(buffer)) != -1) {
                    fileOutputStream.write(buffer, 0, count);
                }

                fileOutputStream.close();
                zipInputStream.closeEntry();
            }

            zipInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

        return tempFolder;
    }

    private void CopyDatabaseInternal() throws IOException {

        File extractedPath = ExtractAssetsZip(DatabaseName + ".zip");
        String databaseFile = "";
        for (File innerFile : extractedPath.listFiles()) {
            databaseFile = innerFile.getAbsolutePath();
            break;
        }
        if (databaseFile == null || databaseFile.length() ==0 )
            throw new RuntimeException("databaseFile is empty");

        InputStream inputStream = new FileInputStream(databaseFile);

        String outFileName = DatabasePath() + DatabaseName;

        File destinationPath = new File(DatabasePath());
        if (!destinationPath.exists())
            destinationPath.mkdirs();

        File destinationFile = new File(outFileName);
        if (!destinationFile.exists())
            destinationFile.createNewFile();

        OutputStream myOutput = new FileOutputStream(outFileName);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

        myOutput.flush();
        myOutput.close();
        inputStream.close();
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int fromVersion, int toVersion) {

    }
}

Bitte beachten Sie: Der Code extrahiert die Datenbankdatei aus einer Zip-Datei in Assets

0voto

Amin Keshavarzian Punkte 3051

Wenn Sie Folgendes verwenden ZIMMER es gibt bereits einen ziemlich geradlinigen Weg https://developer.Android.com/training/data-storage/room/prepopulate in der offiziellen Dokumentation. Hier sehen Sie, wie Sie Ihre Datenbank aus einer Asset-Datei neu befüllen können:

Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromAsset("database/myapp.db")
    .build()

oder aus einer Datei:

Room.databaseBuilder(appContext, AppDatabase.class, "Sample.db")
    .createFromFile(File("mypath"))
    .build()

und wenn Sie Room noch nicht verwenden, empfehle ich Ihnen dringend, dies zu tun

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X