繁体   English   中英

为什么我的 SQLite 数据库没有从 Android Studio 中的资产加载?

[英]Why isn't my SQLite database loading from Assets in Android Studio?

我正在尝试将现有的 SQLite 数据库加载到 Android Studio 中。 但是,数据库适配器返回一个空数据库,而不是给我已填充数据库的副本。

我有我的权限

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

我的数据库适配器

package com.example.testbed;

import android.app.SearchManager;
import android.content.ContentValues;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.util.Log;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;

public class DBAdapter extends SQLiteOpenHelper{
    public static final String TAG = DBAdapter.class.getSimpleName();
    public static int flag;
    private static SQLiteDatabase db;
    private static String DB_NAME = "recipes.db";
    public static String TABLE_NAME = "DrinkRecipes_Loaded";
    public static String DB_PATH = "";
    public static String COL_WORD = "WORD";
    String outFileName = "";
    public static Context myContext;
    private String loadedTable = "DrinkRecipes_Loaded";
    private String specialtyTable = "DrinkRecipes_Specialty";
    private String beautyTable = "DrinkRecipes_Beauty";
    private String kidsTable = "DrinkRecipes_Kids";
    private String shakesTable = "DrinkRecipes_Shakes";



    public DBAdapter(Context context) {
        super(context, DB_NAME, null, 1);
        this.myContext = context;
        ContextWrapper cw = new ContextWrapper(context);
        DB_PATH = "/data/data" + BuildConfig.APPLICATION_ID + "/databases/";
        Log.e(TAG, "Databasehelper: DB_PATH " + DB_PATH);
        outFileName = DB_PATH + DB_NAME;
        File file = new File(DB_PATH);
        Log.e(TAG, "Databasehelper: " + file.exists());
        if (!file.exists()) {
            file.mkdir();
        }
    }

    /**
     * Creates a empty database on the system and rewrites it with your own database.
     */
    public void createDataBase() throws IOException {
        boolean dbExist = checkDataBase();
        if (dbExist) {
            //do nothing - database already exist
        } else {
            //By calling this method and empty database will be created into the default system path
            //of your application so we are gonna be able to overwrite that database with our database.
            this.getReadableDatabase();
            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }

    /**
     * Check if the database already exist to avoid re-copying the file each time you open the application.
     *
     * @return true if it exists, false if it doesn't
     */
    private boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            checkDB = SQLiteDatabase.openDatabase(outFileName, null, SQLiteDatabase.OPEN_READONLY);
        } catch (SQLiteException e) {
            try {
                copyDataBase();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }

        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

    /**
     * Copies your database from your local assets-folder to the just created empty database in the
     * system folder, from where it can be accessed and handled.
     * This is done by transfering bytestream.
     */

    private void copyDataBase() throws IOException {

        Log.i("Database",
                "New database is being copied to device!");
        byte[] buffer = new byte[1024];
        OutputStream myOutput = null;
        int length;
        // Open your local db as the input stream
        InputStream myInput = null;
        try {
            myInput = myContext.getAssets().open(DB_NAME);
            // transfer bytes from the inputfile to the
            // outputfile
            myOutput = new FileOutputStream(DB_PATH + DB_NAME);
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myOutput.close();
            myOutput.flush();
            myInput.close();
            Log.i("Database",
                    "New database has been copied to device!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void openDataBase() throws SQLException {
        //Open the database
        String myPath = DB_PATH + DB_NAME;
        db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
        Log.e(TAG, "openDataBase: Open " + db.isOpen());
    }

    // we have created a new method for reading loaded recipes.
    public ArrayList<recipeModal> readLoadedRecipes() {
        // on below line we are creating a
        // database for reading our database.
        SQLiteDatabase db = this.getReadableDatabase();

        // on below line we are creating a cursor with query to read data from database.
        Cursor cursorRecipes = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);

        // on below line we are creating a new array list.
        ArrayList<recipeModal> recipeModalArrayList = new ArrayList<>();

        // moving our cursor to first position.
        if (cursorRecipes.moveToFirst()) {
            do {
                // on below line we are adding the data from cursor to our array list.
                recipeModalArrayList.add(new recipeModal(cursorRecipes.getString(0),
                        cursorRecipes.getString(1),
                        cursorRecipes.getString(2),
                        cursorRecipes.getString(3),
                        cursorRecipes.getString(4),
                        cursorRecipes.getString(5),
                        cursorRecipes.getString(6),
                        cursorRecipes.getString(7),
                        cursorRecipes.getString(8)));
            } while (cursorRecipes.moveToNext());
            // moving our cursor to next.
        }
        // at last closing our cursor
        // and returning our array list.
        cursorRecipes.close();
        return recipeModalArrayList;
    }

    // we have created a new method for reading loaded recipes.
    public ArrayList<beautyModal> readBeautyRecipes() {
        // on below line we are creating a
        // database for reading our database.
        SQLiteDatabase db = this.getReadableDatabase();

        // on below line we are creating a cursor with query to read data from database.
        Cursor beautyRecipes = db.rawQuery("SELECT * FROM " + beautyTable, null);

        // on below line we are creating a new array list.
        ArrayList<beautyModal> beautyModalArrayList = new ArrayList<>();

        // moving our cursor to first position.
        if (beautyRecipes.moveToFirst()) {
            do {
                // on below line we are adding the data from cursor to our array list.
                beautyModalArrayList.add(new beautyModal(beautyRecipes.getString(0),
                        beautyRecipes.getString(1),
                        beautyRecipes.getString(2),
                        beautyRecipes.getString(3),
                        beautyRecipes.getString(4),
                        beautyRecipes.getString(5)));
            } while (beautyRecipes.moveToNext());
            // moving our cursor to next.
        }
        // at last closing our cursor
        // and returning our array list.
        beautyRecipes.close();
        return beautyModalArrayList;
    }

    // we have created a new method for reading loaded recipes.
    public ArrayList<specialtyModal> readSpecialtyRecipes() {
        // on below line we are creating a
        // database for reading our database.
        SQLiteDatabase db = this.getReadableDatabase();

        // on below line we are creating a cursor with query to read data from database.
        Cursor specialtyRecipes = db.rawQuery("SELECT * FROM " + specialtyTable, null);

        // on below line we are creating a new array list.
        ArrayList<specialtyModal> specialtyModalArrayList = new ArrayList<>();

        // moving our cursor to first position.
        if (specialtyRecipes.moveToFirst()) {
            do {
                // on below line we are adding the data from cursor to our array list.
                specialtyModalArrayList.add(new specialtyModal(specialtyRecipes.getString(0),
                        specialtyRecipes.getString(1),
                        specialtyRecipes.getString(2),
                        specialtyRecipes.getString(3),
                        specialtyRecipes.getString(4),
                        specialtyRecipes.getString(5),
                        specialtyRecipes.getString(6),
                        specialtyRecipes.getString(7)));
            } while (specialtyRecipes.moveToNext());
            // moving our cursor to next.
        }
        // at last closing our cursor
        // and returning our array list.
        specialtyRecipes.close();
        return specialtyModalArrayList;
    }

    // we have created a new method for reading loaded recipes.
    public ArrayList<kidsModal> readKidsRecipes() {
        // on below line we are creating a
        // database for reading our database.
        SQLiteDatabase db = this.getReadableDatabase();

        // on below line we are creating a cursor with query to read data from database.
        Cursor kidsRecipes = db.rawQuery("SELECT * FROM " + kidsTable, null);

        // on below line we are creating a new array list.
        ArrayList<kidsModal> kidsModalArrayList = new ArrayList<>();

        // moving our cursor to first position.
        if (kidsRecipes.moveToFirst()) {
            do {
                // on below line we are adding the data from cursor to our array list.
                kidsModalArrayList.add(new kidsModal(kidsRecipes.getString(0),
                        kidsRecipes.getString(1),
                        kidsRecipes.getString(2),
                        kidsRecipes.getString(3),
                        kidsRecipes.getString(4)));
            } while (kidsRecipes.moveToNext());
            // moving our cursor to next.
        }
        // at last closing our cursor
        // and returning our array list.
        kidsRecipes.close();
        return kidsModalArrayList;
    }

    // we have created a new method for reading loaded recipes.
    public ArrayList<shakesModal> readShakesRecipes() {
        // on below line we are creating a
        // database for reading our database.
        SQLiteDatabase db = this.getReadableDatabase();

        // on below line we are creating a cursor with query to read data from database.
        Cursor shakesRecipes = db.rawQuery("SELECT * FROM " + shakesTable, null);

        // on below line we are creating a new array list.
        ArrayList<shakesModal> shakesModalArrayList = new ArrayList<>();

        // moving our cursor to first position.
        if (shakesRecipes.moveToFirst()) {
            do {
                // on below line we are adding the data from cursor to our array list.
                shakesModalArrayList.add(new shakesModal(shakesRecipes.getString(0),
                        shakesRecipes.getString(1),
                        shakesRecipes.getString(2),
                        shakesRecipes.getString(3),
                        shakesRecipes.getString(4)));
            } while (shakesRecipes.moveToNext());
            // moving our cursor to next.
        }
        // at last closing our cursor
        // and returning our array list.
        shakesRecipes.close();
        return shakesModalArrayList;
    }


    @Override
    public synchronized void close() {
        if (db != null)
            db.close();
        super.close();
    }

    public void onCreate(SQLiteDatabase arg0) {


    }

    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {

    }
}

当我调用它时,我唯一得到的是一个崩溃的应用程序和一个写入正确路径的空数据库。 我非常渴望找到解决此问题的方法,并希望得到任何反馈。

我尝试了几种在 Google 上看起来很有前途的不同解决方案,但没有成功。

编辑:错误的堆栈跟踪


    E/SQLiteLog: (1) no such table: DrinkRecipes_Loaded in "SELECT * FROM DrinkRecipes_Loaded"
    D/AndroidRuntime: Shutting down VM
    E/AndroidRuntime: FATAL EXCEPTION: main
        Process: com.example.testbed, PID: 4732
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testbed/com.example.testbed.ViewRecipes}: android.database.sqlite.SQLiteException: no such table: DrinkRecipes_Loaded (code 1 SQLITE_ERROR[1]): , while compiling: SELECT * FROM DrinkRecipes_Loaded
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3851)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4027)
            at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
            at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
            at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2336)
            at android.os.Handler.dispatchMessage(Handler.java:106)
            at android.os.Looper.loop(Looper.java:247)
            at android.app.ActivityThread.main(ActivityThread.java:8676)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
         Caused by: android.database.sqlite.SQLiteException: no such table: DrinkRecipes_Loaded (code 1 SQLITE_ERROR[1]): , while compiling: SELECT * FROM DrinkRecipes_Loaded
            at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
            at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:1463)
            at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:901)
            at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:590)
            at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:62)
            at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
            at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:46)
            at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:2063)
            at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:2002)
            at com.example.testbed.DBAdapter.readLoadedRecipes(DBAdapter.java:128)
            at com.example.testbed.ViewRecipes.onCreate(ViewRecipes.java:84)
            at android.app.Activity.performCreate(Activity.java:8215)
            at android.app.Activity.performCreate(Activity.java:8199)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3824)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:4027) 
            at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
            at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
            at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2336) 
            at android.os.Handler.dispatchMessage(Handler.java:106) 
            at android.os.Looper.loop(Looper.java:247) 
            at android.app.ActivityThread.main(ActivityThread.java:8676) 
            at java.lang.reflect.Method.invoke(Native Method) 
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130) 

您的代码存在一些问题。

  1. 您正在尝试将数据库文件设为目录而不是将父目录设为目录。

  2. 您不适合后来的 android 版本,这些版本默认使用 WAL(预写日志记录),而不是在创建(复制资产)时使用getReabableDatabase进行日志记录。

  • getReadableDatabase将按照它所说的那样创建数据库。 然后副本会覆盖它(如果有效)。
  • 但是,在 WAL 模式下,会为 WAL 日志记录创建两个附加文件并相应地进行填充。 然后:
  • 复制资产后,SQLite 确定 WAL 文件不是复制数据库的 WAL 文件,因此无法打开可能损坏的数据库。
  • Android API 检测到此故障,但按照要求执行并创建一个空数据库,因此找不到表

使用getReadableDatabase只是为了绕过不存在的数据库目录是矫枉过正/效率低下的,因为创建新数据库的所有处理都已进行。

这是您的代码的重写,请注意:-

  • 所有的访问方法都被注释掉了(而不是创建所有的类)
  • createDatabasecheckDatabase方法已被注释掉。 它们已被getDatabase方法取代。
  • 如果发生 io 错误, CopyDatabase方法已更改为返回 false(getDatabase 然后抛出 runTimeException)

getDatabase方法

  • 检查数据库是否存在,如果存在则返回。 否则,它
  • 检查 parentFile(数据库目录)是否存在,
    • 如果不是,那么它会生成目录(可能还有其他目录,尽管它们应该始终存在)
  • 调用CopyDatabase方法

所以代码(大部分原始代码被注释掉了)是:-

public class DBAdapter extends SQLiteOpenHelper {
   public static final String TAG = DBAdapter.class.getSimpleName();
   public static int flag;
   private static SQLiteDatabase db;
   private static String DB_NAME = "recipes.db";
   public static String TABLE_NAME = "DrinkRecipes_Loaded";
   public static String DB_PATH = "";
   public static String COL_WORD = "WORD";
   String outFileName = "";
   public static Context myContext;
   private String loadedTable = "DrinkRecipes_Loaded";
   private String specialtyTable = "DrinkRecipes_Specialty";
   private String beautyTable = "DrinkRecipes_Beauty";
   private String kidsTable = "DrinkRecipes_Kids";
   private String shakesTable = "DrinkRecipes_Shakes";



   public DBAdapter(Context context) {
      super(context, DB_NAME, null, 1);
      this.myContext = context;
      //ContextWrapper cw = new ContextWrapper(context); Not used
      DB_PATH = context.getDatabasePath(DB_NAME).getPath();  // no need to hard code anything bar the DB name
      /*
      //DB_PATH = "/data/data" + BuildConfig.APPLICATION_ID + "/databases/";
      Log.e(TAG, "Databasehelper: DB_PATH " + DB_PATH);
      outFileName = DB_PATH + DB_NAME;
      File file = new File(DB_PATH);
      Log.e(TAG, "Databasehelper: " + file.exists());
      if (!file.exists()) {
         file.getParentFile().mkdirs(); // CHANGED you don't want the database to be a directory
      }
       */
      getDatabase(context);
   }

   /*<<<<< ADDED >>>>>*/
   private void getDatabase(Context context) {
      File dbFile = new File(context.getDatabasePath((DB_NAME)).getPath());
      if (dbFile.exists()) return; // Database found so all done
      // Otherwise ensure that the database directory exists (does not by default until later versions)
      if (!dbFile.getParentFile().exists()) {
         dbFile.getParentFile().mkdirs();
      }
      if (!copyDataBase()) {
         throw new RuntimeException("Unable to copy database from the asset (check the stack-trace).");
      }
   }

   /**
    * Creates a empty database on the system and rewrites it with your own database.
    */
   /* NOTE NEEDED/UNSAFE as getDatabase create a database and for later version of Android it will be in WAL mode
      thus the additional WAL files are created. When the database is then opened SQLite see that the WAL files are not
      for the copied database and thus the open fails. Android's API then creates an new empty database file
    */
   /*
   public void createDataBase() throws IOException {
      boolean dbExist = checkDataBase();
      if (dbExist) {
         //do nothing - database already exist
      } else {
         //By calling this method and empty database will be created into the default system path
         //of your application so we are gonna be able to overwrite that database with our database.
         this.getReadableDatabase(); // Causes issues if in WAL mode and result in database
         try {
            copyDataBase();
         } catch (IOException e) {
            throw new Error("Error copying database");
         }
      }
   }

    */

   /**
    * Check if the database already exist to avoid re-copying the file each time you open the application.
    *
    * @return true if it exists, false if it doesn't
    */
   /*
   private boolean checkDataBase() {
      SQLiteDatabase checkDB = null;
      try {
         checkDB = SQLiteDatabase.openDatabase(outFileName, null, SQLiteDatabase.OPEN_READONLY);
      } catch (SQLiteException e) {
         try {
            copyDataBase();
         } catch (IOException e1) {
            e1.printStackTrace();
         }
      }

      if (checkDB != null) {
         checkDB.close();
      }
      return checkDB != null ? true : false;
   }

    */

   /**
    * Copies your database from your local assets-folder to the just created empty database in the
    * system folder, from where it can be accessed and handled.
    * This is done by transfering bytestream.
    */

   private boolean /* <<<<< CHANGED SIGNATURE */ copyDataBase() {
      Log.i("Database",
              "New database is being copied to device!");
      byte[] buffer = new byte[4096]; //Probably more efficient as default page size will be 4k
      OutputStream myOutput = null;
      int length;
      // Open your local db as the input stream
      InputStream myInput = null;
      try {
         myInput = myContext.getAssets().open(DB_NAME);
         // transfer bytes from the inputfile to the
         // outputfile
         myOutput = new FileOutputStream(DB_PATH);
         while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
         }
         myOutput.close();
         myOutput.flush();
         myInput.close();
         Log.i("Database",
                 "New database has been copied to device!");
      } catch (IOException e) {
         e.printStackTrace();
         return false;
      }
      return true;
   }

   public void openDataBase() throws SQLException {
      //Open the database
      String myPath = DB_PATH + DB_NAME;
      db = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
      Log.e(TAG, "openDataBase: Open " + db.isOpen());
   }
   /*
   // we have created a new method for reading loaded recipes.
   public ArrayList<recipeModal> readLoadedRecipes() {
      // on below line we are creating a
      // database for reading our database.
      SQLiteDatabase db = this.getReadableDatabase();

      // on below line we are creating a cursor with query to read data from database.
      Cursor cursorRecipes = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);

      // on below line we are creating a new array list.
      ArrayList<recipeModal> recipeModalArrayList = new ArrayList<>();

      // moving our cursor to first position.
      if (cursorRecipes.moveToFirst()) {
         do {
            // on below line we are adding the data from cursor to our array list.
            recipeModalArrayList.add(new recipeModal(cursorRecipes.getString(0),
                    cursorRecipes.getString(1),
                    cursorRecipes.getString(2),
                    cursorRecipes.getString(3),
                    cursorRecipes.getString(4),
                    cursorRecipes.getString(5),
                    cursorRecipes.getString(6),
                    cursorRecipes.getString(7),
                    cursorRecipes.getString(8)));
         } while (cursorRecipes.moveToNext());
         // moving our cursor to next.
      }
      // at last closing our cursor
      // and returning our array list.
      cursorRecipes.close();
      return recipeModalArrayList;
   }

   // we have created a new method for reading loaded recipes.
   public ArrayList<beautyModal> readBeautyRecipes() {
      // on below line we are creating a
      // database for reading our database.
      SQLiteDatabase db = this.getReadableDatabase();

      // on below line we are creating a cursor with query to read data from database.
      Cursor beautyRecipes = db.rawQuery("SELECT * FROM " + beautyTable, null);

      // on below line we are creating a new array list.
      ArrayList<beautyModal> beautyModalArrayList = new ArrayList<>();

      // moving our cursor to first position.
      if (beautyRecipes.moveToFirst()) {
         do {
            // on below line we are adding the data from cursor to our array list.
            beautyModalArrayList.add(new beautyModal(beautyRecipes.getString(0),
                    beautyRecipes.getString(1),
                    beautyRecipes.getString(2),
                    beautyRecipes.getString(3),
                    beautyRecipes.getString(4),
                    beautyRecipes.getString(5)));
         } while (beautyRecipes.moveToNext());
         // moving our cursor to next.
      }
      // at last closing our cursor
      // and returning our array list.
      beautyRecipes.close();
      return beautyModalArrayList;
   }

   // we have created a new method for reading loaded recipes.
   public ArrayList<specialtyModal> readSpecialtyRecipes() {
      // on below line we are creating a
      // database for reading our database.
      SQLiteDatabase db = this.getReadableDatabase();

      // on below line we are creating a cursor with query to read data from database.
      Cursor specialtyRecipes = db.rawQuery("SELECT * FROM " + specialtyTable, null);

      // on below line we are creating a new array list.
      ArrayList<specialtyModal> specialtyModalArrayList = new ArrayList<>();

      // moving our cursor to first position.
      if (specialtyRecipes.moveToFirst()) {
         do {
            // on below line we are adding the data from cursor to our array list.
            specialtyModalArrayList.add(new specialtyModal(specialtyRecipes.getString(0),
                    specialtyRecipes.getString(1),
                    specialtyRecipes.getString(2),
                    specialtyRecipes.getString(3),
                    specialtyRecipes.getString(4),
                    specialtyRecipes.getString(5),
                    specialtyRecipes.getString(6),
                    specialtyRecipes.getString(7)));
         } while (specialtyRecipes.moveToNext());
         // moving our cursor to next.
      }
      // at last closing our cursor
      // and returning our array list.
      specialtyRecipes.close();
      return specialtyModalArrayList;
   }

   // we have created a new method for reading loaded recipes.
   public ArrayList<kidsModal> readKidsRecipes() {
      // on below line we are creating a
      // database for reading our database.
      SQLiteDatabase db = this.getReadableDatabase();

      // on below line we are creating a cursor with query to read data from database.
      Cursor kidsRecipes = db.rawQuery("SELECT * FROM " + kidsTable, null);

      // on below line we are creating a new array list.
      ArrayList<kidsModal> kidsModalArrayList = new ArrayList<>();

      // moving our cursor to first position.
      if (kidsRecipes.moveToFirst()) {
         do {
            // on below line we are adding the data from cursor to our array list.
            kidsModalArrayList.add(new kidsModal(kidsRecipes.getString(0),
                    kidsRecipes.getString(1),
                    kidsRecipes.getString(2),
                    kidsRecipes.getString(3),
                    kidsRecipes.getString(4)));
         } while (kidsRecipes.moveToNext());
         // moving our cursor to next.
      }
      // at last closing our cursor
      // and returning our array list.
      kidsRecipes.close();
      return kidsModalArrayList;
   }

   // we have created a new method for reading loaded recipes.
   public ArrayList<shakesModal> readShakesRecipes() {
      // on below line we are creating a
      // database for reading our database.
      SQLiteDatabase db = this.getReadableDatabase();

      // on below line we are creating a cursor with query to read data from database.
      Cursor shakesRecipes = db.rawQuery("SELECT * FROM " + shakesTable, null);

      // on below line we are creating a new array list.
      ArrayList<shakesModal> shakesModalArrayList = new ArrayList<>();

      // moving our cursor to first position.
      if (shakesRecipes.moveToFirst()) {
         do {
            // on below line we are adding the data from cursor to our array list.
            shakesModalArrayList.add(new shakesModal(shakesRecipes.getString(0),
                    shakesRecipes.getString(1),
                    shakesRecipes.getString(2),
                    shakesRecipes.getString(3),
                    shakesRecipes.getString(4)));
         } while (shakesRecipes.moveToNext());
         // moving our cursor to next.
      }
      // at last closing our cursor
      // and returning our array list.
      shakesRecipes.close();
      return shakesModalArrayList;
   }


    */

   @Override
   public synchronized void close() {
      if (db != null)
         db.close();
      super.close();
   }

   public void onCreate(SQLiteDatabase arg0) {
   }

   @Override
   public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
   }
}

以上已经过测试,但使用重命名为 recipes.db 的替代数据库(NorthWind,因为它非常大)新安装的日志:-

2022-03-27 10:22:11.223 I/Database: New database is being copied to device!
2022-03-27 10:22:11.455 I/Database: New database has been copied to device!

AppInspection 确认数据库已成功复制(尽管不是您的数据库):-

在此处输入图像描述

同样,设备文件资源管理器显示:- 在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM