sql >> Databasteknik >  >> RDS >> SQLite

hur startar man en app med SQLite darabase på Android Studio-emulatorn?

Eftersom du har problem är följande en hastigt ihopsatt handledning tillsammans med kod.

  1. Skapa databasen och tabellerna i ett SQLite-verktyg, lägg till data efter behov och spara dem sedan.

  2. Stäng databasen och öppna den igen för att kontrollera att tabellerna och data är som förväntat. Om inte gör ändringar och upprepa sedan 2 tills du är säker på att den sparade databasen matchar.

  3. Skaffa filnamnet för den sparade databasen och registrera det inklusive filtillägget.

  4. Om du ännu inte har skapat ett projekt för appen gör du det och sparar projektet.

  5. Utanför IDE:n navigera till projektens app/src/huvudmapp och skapa en mapp med namnet tillgångar om det inte redan finns.

  6. Kopiera databasfilen till tillgångsmappen.

  7. Öppna projektet i Android Studio.

  8. Skapa en ny Java-klass med namnet DatabasHelper med SuperClass som SQLiteOpenHelper (kommer att lösas till android.database.sqlite.SQLiteOpenHelper ) och markera Visa markeringar Kryssruta i dialogrutan. Klicka på OK.

Det ska se ut så här:-

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. Lägg till en rad, som en klassvariabel, efter public class DatabaseHelper extends SQLiteOpenHelper { det är som :-

    public static final String DBNAME = "my_dic.db";
    
    • Notera att det är viktigt att värdet inom citattecken är exakt detsamma som filnamnet som kopierades till tillgångsmappen.

.

  1. Lägg till följande klassvariabler

:-

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;
  • Notera att värdena inom citattecken måste matcha respetstabellen/kolumnnamnen som definierades i databasen för TB_BOOKMARK, COL_BOOKMARK_KEY, COL_BOOKMARK_VALUE och COl_BOOKMARK_DATE.
    • DBVERSION kommer att vara versionsnumret som lagras i databasens user_version-fält.
    • SQliteDatabase mDB är en deklaration för en variabel att hålla SQLiteDatabasen när den har öppnats. OBS för närvarande är dess värde null tills det har ställts in.

.

  1. Ändra konstruktorn för klassen Databasehelper från :-

    public DatabaseHelper(Kontextkontext, Stringnamn, SQLiteDatabase.CursorFactory factory, int version) {super(kontext, namn, fabrik, version);}

till :-

public DatabaseHelper(Context context) {
    super(context, DBNAME, null, DBVERSION);
}
  • Detta gör det så att en instans av klassen Databasehelper kan skapas med bara en parameter, kontexten. De andra värdena har definierats eller i fallet med fabriken kommer inga att användas, så null betyder detta.

.

  1. Lägg till en metod, ifDBExists till DatabaseHelper-klassen för att kontrollera om databasen finns (du vill bara kopiera den från tillgångsfilen en gång)

:-

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();
}
  • Förutom att kontrollera att databasfilen finns (observera att den antas vara en giltig databasfil),
  • Om databasen inte finns kan det dessutom vara så att databaskatalogen inte existerar, detta kommer att skapa den om den inte finns.

.

  1. Lägg till en annan metod copyDBFromAssets för att kopiera tillgångsfilen till databasen

:-

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;
}
  • Observera att detta är avsiktligt långrandigt, så att alla fel kan upptäckas.

Den kompletta DatabaseHelper-klassen skulle nu vara :-

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. Ändra konstruktorn för att köra copyDBFromAssets metod när/om databasen inte finns (med hjälp av ifDBExists metod)

:-

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();
}
  • Observera att om det var problem med att kopiera databasen kommer appen att stoppas på grund av RunTimeExcpetion utfärdat.

.

  1. Ändra senast en aktivitets onCreate-metod (skulle normalt vara huvudaktiviteten) för att skapa en instans av klassen DatabaseHelper. Kör sedan appen (om appen har körts är det bäst att ta bort appens data innan du gör det, ifall en databas, kanske tom, har skapats.)

Följande kod innehåller också en fråga som berättar vilka tabeller som finns i databasen :-

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();
    }
}

Baserat på skärmdumpen och en databasfil med namnet my_dic.db . Utdata i loggen är :-

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
  • Detta indikerar att :-
    • Databasen fanns inte och databaskatalogen skapades (dvs. data/data/<package name>/databases )
    • 12288 byte kopierades från tillgångsfilen till databasfilen (dvs. en lyckad kopia gjordes).
    • Den resulterande databasen har tre poster i sqlite_master-tabellen, BookMark-tabellen, en tabell som heter android_metadata (en tabell som automatiskt skapas för Android-enheter av SDK som lagrar lokalen) och ett automatiskt genererat index för BookMark-tabellen.

Efterföljande nummer

Objektet har i princip inte en metod som heter getClass, utan du måste använda fragmentets ärvda getClass-metod. Så du måste omge det returnerade fragmentet inom parentes.

Så istället för :-

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

Du kan använda :-

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

Alternativt kan du använda :-

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

tillsammans med att använda :-

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

istället för att använda if (activeFragment.equals(BookmarkFragment.class.getSimpleName())) { ......




  1. Vad är T-SQL?

  2. Hur man beräknar marginal i MySQL

  3. Motsvarighet till MySQL PÅ DUPLIKATNYCKELUPPDATERING i SQL Server

  4. Kontrollera om filen finns eller inte i sql-servern?