代码之家  ›  专栏  ›  技术社区  ›  NullPointerException

SQLite:没有这样的表错误Android P问题

  •  4
  • NullPointerException  · 技术社区  · 7 年前

    在Android P之前,我的代码一切正常,但现在在Android P中,我在处理数据库时遇到了很多问题。

    我在assets文件夹中存储了.db sqlite数据库文件。我把它们导入android的数据库空间,直到android P。在android P中,我得到了一个例外: SQLite: No Such Table Error

    我在这里搜索了一下,找到了这个,我试着用公认的答案: Android P - 'SQLite: No Such Table Error' after copying database from assets

    问题是,现在我有另一个问题,它仍然不起作用。现在我的问题是 每次我试图检查数据库是否已经存在,这段代码总是返回true,所以我从不创建数据库 . 即使没有创建数据库,即使最近安装了应用程序:

    private boolean checkIfDBExists() {
        File dbFile = new File(DB_COMPLETE_PATH);
        return dbFile.exists();
    }
    

    我的源代码是前面引用的问题中接受答案的源代码。

    public static String getDatabasePath(String fileNname){
        MySQLiteOpenHelper helper = new MySQLiteOpenHelper(ApplicationContextProvider.getContext(), fileNname);
        SQLiteDatabase database = helper.getReadableDatabase();
        String path = database.getPath();
        database.close();
        return path;
    }
    
    public class MySQLiteOpenHelper extends SQLiteOpenHelper {
        public MySQLiteOpenHelper(Context context, String databaseName) {
            super(context, databaseName, null, 2);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
    
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
        }
    
        @Override
        public void onOpen(SQLiteDatabase db) {
            super.onOpen(db);
            db.disableWriteAheadLogging();
        }
    }
    

    我的DBHelper类:

    public class DbHelper extends SQLiteOpenHelper{ 
        private  String DB_NAME;
        private  String DB_COMPLETE_PATH;
        private SQLiteDatabase mDataBase;
        private static final int DATABASE_VERSION = 1;
    
        public DbHelper(String name) throws IOException {
            super(ApplicationContextProvider.getContext(), name+".db", null, DATABASE_VERSION);
            this.DB_NAME = name+".db";
            this.DB_COMPLETE_PATH = Util.getDatabasePath(DB_NAME);
    
            boolean mustOverWriteDB; 
    
            if (checkIfDBExists()==false) {
                createDataBase();
            }
    
            openDataBase();
        }
    
        private void createDataBase() throws IOException {
            this.getReadableDatabase();
            try {           
                copyDataBase();            
            } catch (IOException e) {           
                throw new RuntimeException(e);
            }
        }
    
        public void copyDataBase() throws IOException {
            InputStream myInput = App.getInstance().getAssetsFile(DB_NAME);
            String outFileName = DB_COMPLETE_PATH;
            OutputStream myOutput = new FileOutputStream(outFileName);
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myOutput.flush();
            myOutput.close();
            myInput.close();
        }
    }
    
    3 回复  |  直到 7 年前
        1
  •  13
  •   halfer Jatin Pandey    5 年前

    Arg最终解决了这个问题 this.close(); 之后 this.getReadableDatabase();

    打开的连接正在生成原始的表,没有这样的表异常

    所以我使用了Util.getDatabasePath(DB\u NAME);而不是 Android P - 'SQLite: No Such Table Error' after copying database from assets

    非常感谢@LifeStyle发现了真正的问题。

    现在代码更简单了:

    public static String getDatabasePath(String fileNname){
        return ApplicationContextProvider.getContext().getDatabasePath(fileNname).getAbsolutePath();
    }
    
    public class DbHelper extends SQLiteOpenHelper{
        private String DB_NAME;
        private String DB_COMPLETE_PATH;
        private SQLiteDatabase mDataBase;
        private static final int DATABASE_VERSION = 1;
    
        public DbHelper(String name) throws IOException {
            super(ApplicationContextProvider.getContext(), name+".db", null, DATABASE_VERSION);
            this.DB_NAME = name+".db";
            this.DB_COMPLETE_PATH = Util.getDatabasePath(DB_NAME);
    
            if (checkIfDBExists()==false){
                createDataBase();
            }
    
            openDataBase();
        }
    
        private void createDataBase() throws IOException {
            this.getReadableDatabase();
            this.close();
            try {           
                copyDataBase();            
            } catch (IOException e) {           
                throw new RuntimeException(e);
            }
        }
    
        private boolean checkIfDBExists() {
            File dbFile = new File(DB_COMPLETE_PATH);
            return dbFile.exists();
        }
    }
    
        2
  •  1
  •   LifeStyle    7 年前

    this.DB_COMPLETE_PATH = Util.getDatabasePath(DB_NAME);
    

    通过调用此方法,SQLOpenHelper将创建数据库(在本例中为空,因为在OnCreate()方法中不会发生任何事情)。

    如果您将DB存储在默认应用程序的DB路径中,则可以通过下一个代码段检查DB是否存在:

    File f = context.getDatabasePath("my_database.db");
    if(f.exists()) {
       //Your code if DB exist
    } else {
       //Your code if DB doesn't exist
    }
    

    禁用WAL的更好地方是SQLiteOpenHelper中的onConfigure()方法

        3
  •  0
  •   Suraj Rao Raas Masood    6 年前

    将此路径添加到数据库

    String dbPath = "/data/data/" + mContext.getPackageName() + "/cache/" + mDataBaseName;
    
        4
  •  0
  •   Deepak Rajput    6 年前

        5
  •  -2
  •   aaru    5 年前

    通过添加 this.close(); 之后 this.getReadableDatabase();

    `private void createDataBase() throws IOException {
        this.getReadableDatabase();
        this.close(); 
        try {           
            copyDataBase();            
        } catch (IOException e) {           
            throw new RuntimeException(e);
        }
    }`
    
    [https://stackoverflow.com/a/53258585/4657260][1]
    
    推荐文章