从assets文件夹复制数据库后,android pie中没有此类表错误

从assets文件夹复制数据库后,android pie中没有此类表错误,android,sqlite,android-sqlite,Android,Sqlite,Android Sqlite,从资产文件夹复制数据库后,我无法访问android pie上的数据库。它适用于所有其他版本。在执行数据库操作时,我收到一个“未找到此类列”错误。请帮我解决这个问题。下面是我正在使用的dbhelper类: public class DBHelper extends SQLiteOpenHelper { private static String DB_PATH = "/data/data/com.abc.xyz/databases/"; private static St

从资产文件夹复制数据库后,我无法访问android pie上的数据库。它适用于所有其他版本。在执行数据库操作时,我收到一个“未找到此类列”错误。请帮我解决这个问题。下面是我正在使用的dbhelper类:

public class DBHelper extends SQLiteOpenHelper {

    private static String DB_PATH = "/data/data/com.abc.xyz/databases/";    
    private static String DB_NAME = "db";    
    private SQLiteDatabase myDataBase;    
    private final Context myContext;

    public DBHelper(Context context) {    
        super(context, DB_NAME, null, 1);
        this.myContext = context;
    }

    /**
     * Creates an 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{
            String myPath = DB_PATH + DB_NAME;
            checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
            checkDB.close();
        } catch(SQLiteException e) {

            //database does't exist yet.
        }

        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 {

        //Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);
        // Path to the just created empty db
        String outFileName = DB_PATH + DB_NAME;
        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(outFileName);
        //transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;
        while ((length = myInput.read(buffer))>0) {
            myOutput.write(buffer, 0, length);
        }
        //Close the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();
    }

    public void openDataBase() throws SQLException {

        //Open the database
        String myPath = DB_PATH + DB_NAME;
        myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    }

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

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    }
}

我相信以下内容将解决在检查数据库是否存在时打开数据库的问题,而不是检查数据库是否作为文件存在(请参阅注释):-

阶段1-在不使用资产文件夹中的数据库文件(db)的情况下运行:-
  • 请注意日志
    /VERSION:buildversion中的行是28,即Android Pie
出现异常,包括堆栈跟踪,该堆栈跟踪指向
InputStream myInput=myContext.getAssets().open(DB_NAME)错误(即资产不存在,如预期的那样)。:-

2019-01-25 17:51:12.303 30371-30371/so.cdfa D/VERSION: Build Version is 28
2019-01-25 17:51:12.304 30371-30371/so.cdfa D/COPYDATABASE: Initiated Copy of the database file db from the assets folder.
2019-01-25 17:51:12.304 30371-30371/so.cdfa W/System.err: java.io.FileNotFoundException: db
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.content.res.AssetManager.nativeOpenAsset(Native Method)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:744)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:721)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at so.cdfa.DBHelper.copyDataBase(DBHelper.java:101)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at so.cdfa.DBHelper.createDataBase(DBHelper.java:55)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at so.cdfa.DBHelper.<init>(DBHelper.java:36)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at so.cdfa.MainActivity.onCreate(MainActivity.java:18)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.app.Activity.performCreate(Activity.java:7136)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.app.Activity.performCreate(Activity.java:7127)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:106)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.os.Looper.loop(Looper.java:193)
2019-01-25 17:51:12.307 30371-30371/so.cdfa W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6669)
2019-01-25 17:51:12.307 30371-30371/so.cdfa W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2019-01-25 17:51:12.307 30371-30371/so.cdfa W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
2019-01-25 17:51:12.307 30371-30371/so.cdfa W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2019-01-25 17:51:12.307 30371-30371/so.cdfa D/AndroidRuntime: Shutting down VM
2019-01-25 17:51:12.312 30371-30371/so.cdfa E/AndroidRuntime: FATAL EXCEPTION: main
    Process: so.cdfa, PID: 30371
    java.lang.RuntimeException: Unable to start activity ComponentInfo{so.cdfa/so.cdfa.MainActivity}: java.lang.RuntimeException: Error copying database (see stack-trace above)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.RuntimeException: Error copying database (see stack-trace above)
        at so.cdfa.DBHelper.createDataBase(DBHelper.java:62)
        at so.cdfa.DBHelper.<init>(DBHelper.java:36)
        at so.cdfa.MainActivity.onCreate(MainActivity.java:18)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
2019-01-25 17:51:12.330 30371-30371/so.cdfa I/Process: Sending signal. PID: 30371 SIG: 9

我所要做的就是在之后关闭数据库连接。getReadableDatabase()createDataBase()中:

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();
        this.close()
        try {
            copyDataBase();
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }   
}

我已经为此挣扎了好几天了。刚刚通过从createDatabase()方法中删除以下代码行解决了此问题:


API 27和28现在似乎可以正常工作。

您的复制数据库功能有一些不相关的问题-如果抛出异常,它不会关闭输出流,因此可能会泄漏资源。可能的复制在android上仍然没有运气。请看最后一个注记,我实际上不明白这一点。您能解释一下吗?文件已成功复制到系统文件夹中,但仍然没有显示此类表错误:(@AkhilSudha)你需要阅读并遵循完整的答案。
2019-01-25 17:51:12.303 30371-30371/so.cdfa D/VERSION: Build Version is 28
2019-01-25 17:51:12.304 30371-30371/so.cdfa D/COPYDATABASE: Initiated Copy of the database file db from the assets folder.
2019-01-25 17:51:12.304 30371-30371/so.cdfa W/System.err: java.io.FileNotFoundException: db
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.content.res.AssetManager.nativeOpenAsset(Native Method)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:744)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.content.res.AssetManager.open(AssetManager.java:721)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at so.cdfa.DBHelper.copyDataBase(DBHelper.java:101)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at so.cdfa.DBHelper.createDataBase(DBHelper.java:55)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at so.cdfa.DBHelper.<init>(DBHelper.java:36)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at so.cdfa.MainActivity.onCreate(MainActivity.java:18)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.app.Activity.performCreate(Activity.java:7136)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.app.Activity.performCreate(Activity.java:7127)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
2019-01-25 17:51:12.305 30371-30371/so.cdfa W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:106)
2019-01-25 17:51:12.306 30371-30371/so.cdfa W/System.err:     at android.os.Looper.loop(Looper.java:193)
2019-01-25 17:51:12.307 30371-30371/so.cdfa W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:6669)
2019-01-25 17:51:12.307 30371-30371/so.cdfa W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2019-01-25 17:51:12.307 30371-30371/so.cdfa W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
2019-01-25 17:51:12.307 30371-30371/so.cdfa W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
2019-01-25 17:51:12.307 30371-30371/so.cdfa D/AndroidRuntime: Shutting down VM
2019-01-25 17:51:12.312 30371-30371/so.cdfa E/AndroidRuntime: FATAL EXCEPTION: main
    Process: so.cdfa, PID: 30371
    java.lang.RuntimeException: Unable to start activity ComponentInfo{so.cdfa/so.cdfa.MainActivity}: java.lang.RuntimeException: Error copying database (see stack-trace above)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.RuntimeException: Error copying database (see stack-trace above)
        at so.cdfa.DBHelper.createDataBase(DBHelper.java:62)
        at so.cdfa.DBHelper.<init>(DBHelper.java:36)
        at so.cdfa.MainActivity.onCreate(MainActivity.java:18)
        at android.app.Activity.performCreate(Activity.java:7136)
        at android.app.Activity.performCreate(Activity.java:7127)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1271)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2893)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
2019-01-25 17:51:12.330 30371-30371/so.cdfa I/Process: Sending signal. PID: 30371 SIG: 9
2019-01-25 17:54:51.734 30587-30587/so.cdfa D/VERSION: Build Version is 28
2019-01-25 17:54:51.735 30587-30587/so.cdfa D/COPYDATABASE: Initiated Copy of the database file db from the assets folder.
2019-01-25 17:54:51.735 30587-30587/so.cdfa D/COPYDATABASE: Asset file db found so attmepting to copy to /data/user/0/so.cdfa/databases/db
2019-01-25 17:54:51.736 30587-30587/so.cdfa D/COPYDATABASE: Ateempting copy of block 1 which has 1024 bytes.
............. lines removed from brevity 
2019-01-25 17:54:51.746 30587-30587/so.cdfa D/COPYDATABASE: Ateempting copy of block 40 which has 1024 bytes.
2019-01-25 17:54:51.746 30587-30587/so.cdfa D/COPYDATABASE: Finished copying Database db from the assets folder, to  /data/user/0/so.cdfa/databases/db40960were copied, in 40 blocks of size 1024.
2019-01-25 17:54:51.746 30587-30587/so.cdfa D/COPYDATABASE: All Streams have been flushed and closed.
2019-01-25 17:54:51.770 30587-30587/so.cdfa D/DBCONFIGURE: Database has been configured 
2019-01-25 17:54:51.772 30587-30587/so.cdfa D/DBOPENED: Database has been opened.
2019-01-25 17:54:51.772 30587-30587/so.cdfa D/DBITEMS: Found sqlite_sequence which has a type of table the SQL used to create it, was :-
        CREATE TABLE sqlite_sequence(name,seq)
2019-01-25 17:54:51.773 30587-30587/so.cdfa D/DBITEMS: Found Schedules which has a type of table the SQL used to create it, was :-
        CREATE TABLE `Schedules` (
      `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
      `date` REAL
    )
2019-01-25 17:54:51.773 30587-30587/so.cdfa D/DBITEMS: Found type_affinity_example which has a type of table the SQL used to create it, was :-
        CREATE TABLE type_affinity_example (
        id INTEGER PRIMARY KEY, -- <<<<<<<< MUST BE INTEGER VALUE ELSE INVALID DATATYPE
        col1 rumplestiltskin,
        col2 BLOB,
        col3 INTEGER,
        col4 NUMERIC,
        col5 REAL,
        col6 REALINT, -- because of rule 1 will be INTEGER type affinity NOT REAL!!!!
        col7 TEXT
    )
2019-01-25 17:54:51.773 30587-30587/so.cdfa D/DBITEMS: Found OHLCV_Components which has a type of table the SQL used to create it, was :-
        CREATE TABLE OHLCV_Components (symbol TEXT, tradeDate TEXT, openPrice REAL, highPrice REAL, lowPrice REAL, closePrice REAL, volume INTEGER)
2019-01-25 17:54:51.773 30587-30587/so.cdfa D/DBITEMS: Found league which has a type of table the SQL used to create it, was :-
        CREATE TABLE league (league_id INTEGER PRIMARY KEY, league_name TEXT)
2019-01-25 17:54:51.773 30587-30587/so.cdfa D/DBITEMS: Found team which has a type of table the SQL used to create it, was :-
        CREATE TABLE team (team_id INTEGER PRIMARY KEY, team_name TEXT)
2019-01-25 17:54:51.773 30587-30587/so.cdfa D/DBITEMS: Found player which has a type of table the SQL used to create it, was :-
        CREATE TABLE player (player_id INTEGER PRIMARY KEY, player_name)
2019-01-25 17:54:51.773 30587-30587/so.cdfa D/DBITEMS: Found team_league_history which has a type of table the SQL used to create it, was :-
        CREATE TABLE team_league_history (
        tlh_team_reference INTEGER, 
        tlh_league_reference INTEGER, 
        tlh_from_date TEXT DEFAULT CURRENT_DATE, 
        tlh_to_date TEXT DEFAULT '3000-12-31'
    )
2019-01-25 17:54:51.773 30587-30587/so.cdfa D/DBITEMS: Found player_team_history which has a type of table the SQL used to create it, was :-
        CREATE TABLE player_team_history (
        pth_player_reference INTEGER, 
        pth_team_reference INTEGER, 
        pth_from_date TEXT DEFAULT CURRENT_DATE, 
        pth_to_date TEXT DEFAULT '3000-12-31'
    )
2019-01-25 17:54:51.774 30587-30587/so.cdfa D/DBITEMS: Found android_metadata which has a type of table the SQL used to create it, was :-
        CREATE TABLE android_metadata (locale TEXT)
2019-01-25 17:59:32.868 30666-30666/so.cdfa D/VERSION: Build Version is 28
2019-01-25 17:59:32.873 30666-30666/so.cdfa D/DBCONFIGURE: Database has been configured 
2019-01-25 17:59:32.874 30666-30666/so.cdfa D/DBOPENED: Database has been opened.
2019-01-25 17:59:32.875 30666-30666/so.cdfa D/DBITEMS: Found sqlite_sequence which has a type of table the SQL used to create it, was :-
        CREATE TABLE sqlite_sequence(name,seq)
2019-01-25 17:59:32.875 30666-30666/so.cdfa D/DBITEMS: Found Schedules which has a type of table the SQL used to create it, was :-
        CREATE TABLE `Schedules` (
      `id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
      `date` REAL
...........
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();
        this.close()
        try {
            copyDataBase();
        } catch (IOException e) {
            throw new Error("Error copying database");
        }
    }   
}
this.getReadableDataBase();