从数据库Android错误中检索数据

时间:2018-11-26 14:21:29

标签: java android sqlite

我尝试使用sqlite数据库,但问题显示“没有这样的表”,该代码在某些设备上有效,并且某些显示该消息。

class DatabaseHelper extends SQLiteOpenHelper {

    private final String mDatabaseName;
    private final Context mContext;
    private final String mPath;

    DatabaseHelper(Context context, String database, String path){
        super(context,database,null,1);
        this.mContext=context;
        this.mDatabaseName=database;
        this.mPath=path;
        _createDatabase();

    }

    private void _createDatabase() {
        if(_checkDatabase()){
            return;
        }
        getReadableDatabase();
        try {
            _copyDatabase();
        }catch (Exception e){
        }
    }

    private void _copyDatabase() throws IOException {
        InputStream inputStream = mContext.getAssets().open(mDatabaseName);
        FileOutputStream fileOutputStream = new FileOutputStream(mPath+mDatabaseName);
        byte[] bytes = new byte[1024];
        do{
            int n;
            if((n=inputStream.read(bytes)) <= 0){
                fileOutputStream.flush();
                fileOutputStream.close();
                return;
            }
            fileOutputStream.write(bytes,0,n);
        }while (true);

    }

    private boolean _checkDatabase() {
        return mContext.getDatabasePath(mDatabaseName).exists();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

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

    }
}

数据库适配器看起来像这样

class DatabaseAdapter
{
    private SQLiteDatabase database;
    private DatabaseHelper databaseHelper;


    DatabaseAdapter(Context context, String database, String path){
        databaseHelper = new DatabaseHelper(context, database, path);
    }

    void open(){
        try{
            database = databaseHelper.getReadableDatabase();
        }
        catch (SQLiteException e)
        {
            database = databaseHelper.getReadableDatabase();
        }
    }
    boolean isOpened()
    {
        return this.database != null && this.database.isOpen();
    }

    Cursor _get_rows()
    {
        Cursor cursor = database.rawQuery("SELECT * FROM rows ORDER BY RANDOM() LIMIT 4;", null);
        cursor.moveToFirst();
        return cursor;
    }
}

然后数据库控制器看一下

public class DatabaseController {
    private static DatabaseAdapter databaseAdapter;

    public static Cursor _get_rows()
    {
        if(!databaseAdapter.isOpened()){
            databaseAdapter.open();
        }
        return databaseAdapter._get_rows();
    }

    public static void initilization(Context activity) {
        String dbName=  "data.db";
        databaseAdapter = new DatabaseAdapter(activity.getApplicationContext(),dbName,"/data/data/"+activity.getApplicationInfo().packageName+"/databases/");
    }

}

我在这样的活动中使用

DatabaseController.initilization(this);
        Cursor c = DatabaseController._get_rows();

我找不到解决此问题的方法,数据库已经复制到整个目录

1 个答案:

答案 0 :(得分:0)

我怀疑问题是您在:-

中捕获了一个异常
private void _createDatabase() {
    if(_checkDatabase()){
        return;
    }
    getReadableDatabase();
    try {
        _copyDatabase();
    }catch (Exception e){
    }
}

因此处理继续进行,并且创建了一个空数据库,因此没有表。

根本原因可能是数据库目录可能不存在。您需要查看已捕获的异常以确定确切的错误。例如e.printStackTrace();

以下是如何创建数据库目录(以解决可能是问题的ENOENT (No such file or directory)异常):- 例如

private void _copyDatabase() throws IOException {
    File dir = new File(mPath); //<<<<<<<<<< ADDED
    if(!dir.exists()) { //<<<<<<<<<< ADDED
        dir.mkdirs(); //<<<<<<<<<< ADDED
    } //<<<<<<<<<< ADDED
    InputStream inputStream = mContext.getAssets().open(mDatabaseName);
    FileOutputStream fileOutputStream = new FileOutputStream(mPath+mDatabaseName);
    byte[] bytes = new byte[1024];
    do{
        int n;
        if((n=inputStream.read(bytes)) <= 0){
            fileOutputStream.flush();
            fileOutputStream.close();
            return;
        }
        fileOutputStream.write(bytes,0,n);
    }while (true);
}

也不建议使用硬代码路径,例如使用:-

databaseAdapter = new DatabaseAdapter(activity.getApplicationContext(),dbName,"/data/data/"+activity.getApplicationInfo().packageName+"/databases/");

最好使用Context的getDatabasePath方法获取路径。

  • 请注意,该代码是内部代码,未经测试或运行,因此可能包含错误。
  • 请注意在遇到问题的设备上,需要先删除数据库(清除应用程序的数据或卸载应用程序),然后再运行任何修改的代码。