sql >> Database >  >> RDS >> SQLite

hoe de app te starten met SQLite darabase op de Android Studio-emulator?

Omdat je problemen hebt, is het volgende een haastig samengestelde tutorial samen met code.

  1. Maak de database en tabellen in een SQLite-tool, voeg indien nodig gegevens toe en sla deze vervolgens op.

  2. Sluit de database en open deze opnieuw om te controleren of de tabellen en gegevens zijn zoals verwacht. Als er geen wijzigingen zijn, herhaal dan 2 totdat u zeker weet dat de opgeslagen database overeenkomt.

  3. Verkrijg de bestandsnaam van de opgeslagen database en noteer deze inclusief de bestandsextensie.

  4. Als je nog geen project voor de app hebt gemaakt, doe dat dan en sla het project op.

  5. Ga buiten de IDE naar de map projects app/src/main en maak een map met de naam assets als het nog niet bestaat.

  6. Kopieer het databasebestand naar de activamap.

  7. Open het project in Android Studio.

  8. Maak een nieuwe Java-klasse met de naam DatabaseHelper met SuperClass als SQLiteOpenHelper (zal oplossen naar android.database.sqlite.SQLiteOpenHelper ) en vink de Toon Select Overrides . aan Dialoogvenster. De klik op OK.

Het zou er als volgt uit moeten zien:-

public class DatabaseHelper extends SQLiteOpenHelper {
    public Databasehelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

    }
}
  1. Voeg een regel toe als klassevariabele nadat public class DatabaseHelper extends SQLiteOpenHelper { dat is als:-

    public static final String DBNAME = "my_dic.db";
    
    • We merken op dat het belangrijk is dat de waarde tussen de aanhalingstekens exact hetzelfde is als de bestandsnaam die naar de activamap is gekopieerd.

.

  1. Voeg de volgende klassevariabelen toe

:-

public static final int DBVERSION = 1;
public static final String TB_BOOKMARK = "Bookmark";
public static final String COL_BOOKMARK_KEY = "key";
public static final String COL_BOOKMARK_VALUE = "value";
public static final String COL_BOOKMARK_DATE = "date";
SQLiteDatabase mDB;
  • De waarden tussen aanhalingstekens moeten overeenkomen met de namen van de respetice-tabel/kolommen die zijn gedefinieerd in de database voor TB_BOOKMARK, COL_BOOKMARK_KEY, COL_BOOKMARK_VALUE en COl_BOOKMARK_DATE.
    • DBVERSION is het versienummer dat is opgeslagen in het veld user_version van de database.
    • SQliteDatabase mDB is een declaratie voor een variabele die de SQLiteDatabase bevat wanneer deze is geopend. OPMERKING momenteel is de waarde null totdat deze is ingesteld.

.

  1. Wijzig de constructor voor de klasse Databasehelper van:-

    public DatabaseHelper(Contextcontext, Stringnaam, SQLiteDatabase.CursorFactory factory, int version) {super(context, name, factory, version);}

naar:-

public DatabaseHelper(Context context) {
    super(context, DBNAME, null, DBVERSION);
}
  • Dit zorgt ervoor dat een instantie van de klasse Databasehelper kan worden gemaakt met slechts één parameter, de context. De andere waarden zijn gedefinieerd of in het geval van de fabriek zullen er geen worden gebruikt, dus null betekent dit.

.

  1. Voeg een methode toe, ifDBExists naar de DatabaseHelper-klasse om te controleren of de database bestaat (u wilt deze maar één keer uit het activabestand kopiëren)

:-

private boolean ifDBExists(Context context) {
    String dbparent = context.getDatabasePath(DBNAME).getParent();
    File f = context.getDatabasePath(DBNAME);
    if (!f.exists()) {
        Log.d("NODB MKDIRS","Database file not found, making directories."); //<<<< remove before the App goes live.
        File d = new File(dbparent);
        d.mkdirs();
        //return false;
    }
    return f.exists();
}
  • Naast het controleren of het databasebestand bestaat (merk op dat het een geldig databasebestand is),
  • Bovendien, als de database niet bestaat, kan het zijn dat de databasedirectory niet bestaat, hierdoor wordt deze aangemaakt als deze niet bestaat.

.

  1. Een andere methode toevoegen copyDBFromAssets om het activabestand naar de database te kopiëren

:-

private boolean copyDBFromAssets(Context context) {
    Log.d("CPYDBINFO","Starting attemtpt to cop database from the assets file.");
    String DBPATH = context.getDatabasePath(DBNAME).getPath();
    InputStream is;
    OutputStream os;
    int length = 8192;
    long bytes_read = 0;
    long bytes_written = 0;
    byte[] buffer = new byte[length];

    try {

        is = context.getAssets().open(DBNAME);
    } catch (IOException e) {
        Log.e("CPYDB FAIL - NO ASSET","Failed to open the Asset file " + DBNAME);
        e.printStackTrace();
        return false;
    }

    try {
        os = new FileOutputStream(DBPATH);
    } catch (IOException e) {
        Log.e("CPYDB FAIL - OPENDB","Failed to open the Database File at " + DBPATH);
        e.printStackTrace();
        return false;
    }
    Log.d("CPYDBINFO","Initiating copy from asset file" + DBNAME + " to " + DBPATH);
    while (length >= 8192) {
        try {
            length = is.read(buffer,0,length);
        } catch (IOException e) {
            Log.e("CPYDB FAIL - RD ASSET",
                    "Failed while reading in data from the Asset. " +
                            String.valueOf(bytes_read) +
                            " bytes read ssuccessfully."
            );
            e.printStackTrace();
            return false;
        }
        bytes_read = bytes_read + length;
        try {
            os.write(buffer,0,length);
        } catch (IOException e) {
            Log.e("CPYDB FAIL - WR ASSET","failed while writing Database File " +
                    DBPATH +
                    ". " +
            String.valueOf(bytes_written) +
                    " bytes written successfully.");
            e.printStackTrace();
            return false;

        }
        bytes_written = bytes_written + length;
    }
    Log.d("CPYDBINFO",
            "Read " + String.valueOf(bytes_read) + " bytes. " +
                    "Wrote " + String.valueOf(bytes_written) + " bytes."
    );
    try {
        os.flush();
        is.close();
        os.close();
    } catch (IOException e ) {
        Log.e("CPYDB FAIL - FINALISING","Failed Finalising Database Copy. " +
                String.valueOf(bytes_read) +
                " bytes read." +
                String.valueOf(bytes_written) +
                " bytes written."
        );
        e.printStackTrace();
        return false;
    }
    return true;
}
  • Houd er rekening mee dat dit opzettelijk langdradig is, zodat elke storing nauwkeurig kan worden vastgesteld.

De volledige DatabaseHelper-klasse zou nu zijn:-

public class DatabaseHelper extends SQLiteOpenHelper {

    public static final String DBNAME = "my_dic.db"; // <<<< VERY IMPORTANT THAT THIS MATCHES DATABASE FILE NAME
    public static final int DBVERSION = 1;
    public static final String TB_BOOKMARK = "Bookmark";
    public static final String COL_BOOKMARK_KEY = "key";
    public static final String COL_BOOKMARK_VALUE = "value";
    public static final String COL_BOOKMARK_DATE = "date";
    SQLiteDatabase mDB;

    public DatabaseHelper(Context context) {
        super(context, DBNAME, null, DBVERSION);
        if (!ifDBExists(context)) {
            if (!copyDBFromAssets(context)) {
                throw new RuntimeException("Failed to Copy Database From Assets Folder");
            }
        }
        mDB = this.getWritableDatabase();
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
    }

    private boolean ifDBExists(Context context) {
        String dbparent = context.getDatabasePath(DBNAME).getParent();
        File f = context.getDatabasePath(DBNAME);
        if (!f.exists()) {
            Log.d("NODB MKDIRS","Database file not found, making directories.");
            File d = new File(dbparent);
            d.mkdirs();
            //return false;
        }
        return f.exists();
    }

    private boolean copyDBFromAssets(Context context) {
        Log.d("CPYDBINFO","Starting attemtpt to cop database from the assets file.");
        String DBPATH = context.getDatabasePath(DBNAME).getPath();
        InputStream is;
        OutputStream os;
        int length = 8192;
        long bytes_read = 0;
        long bytes_written = 0;
        byte[] buffer = new byte[length];

        try {

            is = context.getAssets().open(DBNAME);
        } catch (IOException e) {
            Log.e("CPYDB FAIL - NO ASSET","Failed to open the Asset file " + DBNAME);
            e.printStackTrace();
            return false;
        }

        try {
            os = new FileOutputStream(DBPATH);
        } catch (IOException e) {
            Log.e("CPYDB FAIL - OPENDB","Failed to open the Database File at " + DBPATH);
            e.printStackTrace();
            return false;
        }
        Log.d("CPYDBINFO","Initiating copy from asset file" + DBNAME + " to " + DBPATH);
        while (length >= 8192) {
            try {
                length = is.read(buffer,0,length);
            } catch (IOException e) {
                Log.e("CPYDB FAIL - RD ASSET",
                        "Failed while reading in data from the Asset. " +
                                String.valueOf(bytes_read) +
                                " bytes read ssuccessfully."
                );
                e.printStackTrace();
                return false;
            }
            bytes_read = bytes_read + length;
            try {
                os.write(buffer,0,length);
            } catch (IOException e) {
                Log.e("CPYDB FAIL - WR ASSET","failed while writing Database File " +
                        DBPATH +
                        ". " +
                String.valueOf(bytes_written) +
                        " bytes written successfully.");
                e.printStackTrace();
                return false;

            }
            bytes_written = bytes_written + length;
        }
        Log.d("CPYDBINFO",
                "Read " + String.valueOf(bytes_read) + " bytes. " +
                        "Wrote " + String.valueOf(bytes_written) + " bytes."
        );
        try {
            os.flush();
            is.close();
            os.close();
        } catch (IOException e ) {
            Log.e("CPYDB FAIL - FINALISING","Failed Finalising Database Copy. " +
                    String.valueOf(bytes_read) +
                    " bytes read." +
                    String.valueOf(bytes_written) +
                    " bytes written."
            );
            e.printStackTrace();
            return false;
        }
        return true;
    }
}

.

  1. Wijzig de constructor om de copyDBFromAssets . uit te voeren methode wanneer/als de database niet bestaat (met behulp van de ifDBExists methode)

:-

public DatabaseHelper(Context context) {
    super(context, DBNAME, null, DBVERSION);
    if (!ifDBExists(context)) {
        if (!copyDBFromAssets(context)) {
            throw new RuntimeException("Failed to Copy Database From Assets Folder");
        }
    }
    mDB = this.getWritableDatabase();
}
  • Let op als er een probleem was met het kopiëren van de database, dan wordt de app gestopt vanwege de RunTimeExcpetion uitgegeven.

.

  1. Laatste wijziging van de methode onCreate van een activiteit (normaal gesproken de hoofdactiviteit) om een ​​instantie van de klasse DatabaseHelper te maken. Voer vervolgens de app uit (als de app is uitgevoerd, kunt u het beste de gegevens van de app verwijderen voordat u dit doet, voor het geval er een database is gemaakt, misschien wel leeg.)

De volgende code bevat ook een query die u zal vertellen welke tabellen er in de database bestaan:-

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        DatabaseHelper mDBHlpr = new DatabaseHelper(this);
        Cursor csr = mDBHlpr.getWritableDatabase().query(
                "sqlite_master",
                null,null,null,null,null,null
        );
        while (csr.moveToNext()) {
            Log.d("DB TABLES", csr.getString(csr.getColumnIndex("name")));
        }
        csr.close();
    }
}

Gebaseerd op de screenshot en een databasebestand met de naam my_dic.db . De uitvoer in het logboek is:-

06-16 02:28:45.208 4467-4467/? D/NODB MKDIRS: Database file not found, making directories.
06-16 02:28:45.208 4467-4467/? D/CPYDBINFO: Starting attemtpt to cop database from the assets file.
    Initiating copy from asset filemy_dic.db to /data/data/com.mydictionaryapp.mydictionaryapp/databases/my_dic.db
    Read 12288 bytes. Wrote 12288 bytes.
06-16 02:28:45.224 4467-4467/? D/DB TABLES: Bookmark
    sqlite_autoindex_Bookmark_1
    android_metadata
  • Dit geeft aan dat :-
    • De database bestond niet en de databasemap is gemaakt (d.w.z. data/data/<package name>/databases )
    • 12288 bytes zijn gekopieerd van het activabestand naar het databasebestand (d.w.z. er is een succesvolle kopie gemaakt).
    • De resulterende database heeft drie items in de sqlite_master-tabel, de BookMark-tabel, een tabel met de naam android_metadata (een tabel die automatisch wordt gemaakt voor Android-apparaten door de SDK die de landinstelling opslaat) en een automatisch gegenereerde index voor de BookMark-tabel.
    • li>

Volgende uitgave

In principe heeft het object geen methode genaamd getClass, maar moet je de overgeërfde getClass-methode van het fragment gebruiken. U moet het geretourneerde fragment dus tussen haakjes plaatsen.

Dus in plaats van:-

String activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container).getClass().getSimpleName();

Je zou kunnen gebruiken:-

String activeFragment = (getSupportFragmentManager().findFragmentById(R.id.fragment_container)).getClass().getSimpleName();

Als alternatief kunt u gebruiken:-

Fragment activeFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);

samen met het gebruik van:-

if (activeFragment instanceOf BookmarkFragment) { ...... rest of your code

in plaats van if (activeFragment.equals(BookmarkFragment.class.getSimpleName())) { ...... te gebruiken




  1. PostgreSQL-functieaanroep

  2. Postgres-dump van alleen delen van tabellen voor een dev-snapshot

  3. Gids voor het ontwerpen van een database voor meldingen in MySQL

  4. Filter op uitvoerclausule sql