ErrorCopyingDataBase异常当我尝试打开SQLite DB时

时间:2012-12-13 17:36:35

标签: android android-sqlite

当我尝试使用方法

打开assets文件夹中的数据库时
  public void loadDatabase(String dbName){
    System.out.println("dbName");
    DataBaseAdapterNew mDbHelper = new DataBaseAdapterNew(
                    this, dbName);
            mDbHelper.createDatabase();
            mDbHelper.open();

    }

我得到致命的例外 ErrorCopyingDataBase

错误堆栈

12-13 18:21:29.179: E/AndroidRuntime(10230): FATAL EXCEPTION: main
12-13 18:21:29.179: E/AndroidRuntime(10230): java.lang.Error: ErrorCopyingDataBase
12-13 18:21:29.179: E/AndroidRuntime(10230):    at com.my.app.db.DataBaseHelper.createDataBase(DataBaseHelper.java:43)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at com.my.app.db.DataBaseAdapterNew.createDatabase(DataBaseAdapterNew.java:42)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at com.my.app.MyActivity.loadDatabase(MyActivity.java:133)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at com.my.app.MyActivity$InvocazioneAsincrona$1.run(MyActivity.java:173)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at android.os.Handler.handleCallback(Handler.java:587)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at android.os.Handler.dispatchMessage(Handler.java:92)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at android.os.Looper.loop(Looper.java:130)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at android.app.ActivityThread.main(ActivityThread.java:3687)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at java.lang.reflect.Method.invokeNative(Native Method)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at java.lang.reflect.Method.invoke(Method.java:507)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
12-13 18:21:29.179: E/AndroidRuntime(10230):    at dalvik.system.NativeStart.main(Native Method)

我的DatabaseAdapterNew类是:

public class DataBaseAdapterNew {

    protected static final String TAG = "DataAdapter";

    private final Context mContext;
    private SQLiteDatabase mDb;
    private DataBaseHelper mDbHelper;

    public DataBaseAdapterNew(Context context, String nameDB) {
        this.mContext = context;
        mDbHelper = new DataBaseHelper(mContext, nameDB);
    }

    public DataBaseAdapterNew createDatabase() throws SQLException {
        try {
            mDbHelper.createDataBase();
        } catch (IOException mIOException) {
            Log.e(TAG, mIOException.toString() + "  UnableToCreateDatabase");
            throw new Error("UnableToCreateDatabase");
        }
        return this;
    }

    public DataBaseAdapterNew open() throws SQLException {
        try {
            mDbHelper.openDataBase();
            mDbHelper.close();
            mDb = mDbHelper.getReadableDatabase();
        } catch (SQLException mSQLException) {
            Log.e(TAG, "open >>" + mSQLException.toString());
            throw mSQLException;
        }
        return this;
    }

    public void close() {
        mDbHelper.close();
    }

    public Cursor allData() {
        try {
            Cursor c = mDb.rawQuery(
                    "SELECT * FROM myTable order by Quantity desc", null);
            if (c != null) {
                c.moveToNext();
            }
            return c;
        } catch (SQLException mSQLException) {
            Log.e(TAG, "allData >>" + mSQLException.toString());
            throw mSQLException;
        }

    }



    }

我的DatabaseHelper类是:

public class DataBaseHelper extends SQLiteOpenHelper {
    private static String TAG = "DataBaseHelper"; 
    private static String DB_PATH = "";
    private static String DB_NAME = "";
    private SQLiteDatabase mDataBase;
    private final Context mContext;

    public DataBaseHelper(Context context, String nomeDB) {
        super(context, nomeDB, null, 1);// 1? its Database Version
        DB_NAME = nomeDB;
        DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        this.mContext = context;
    }

    public void createDataBase() throws IOException {
        // If database not exists copy it from the assets

        boolean mDataBaseExist = checkDataBase();
        if (!mDataBaseExist) {
            this.getReadableDatabase();
            this.close();
            try {
                // Copia il database dalla cartella assests
                copyDataBase();
                Log.e(TAG, "createDatabase database created");
            } catch (IOException mIOException) {
                throw new Error("ErrorCopyingDataBase");
            }
        }
    }

    private boolean checkDataBase() {
        File dbFile = new File(DB_PATH + DB_NAME);
        return dbFile.exists();
    }

    private void copyDataBase() throws IOException {
        InputStream mInput = mContext.getAssets().open(DB_NAME);
        String outFileName = DB_PATH + DB_NAME;
        OutputStream mOutput = new FileOutputStream(outFileName);
        byte[] mBuffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(mBuffer)) > 0) {
            mOutput.write(mBuffer, 0, mLength);
        }
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    public boolean openDataBase() throws SQLException {
        String mPath = DB_PATH + DB_NAME;
        mDataBase = SQLiteDatabase.openDatabase(mPath, null,
                SQLiteDatabase.CREATE_IF_NECESSARY);
        return mDataBase != null;
    }

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

    @Override
    public void onCreate(SQLiteDatabase arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub

    }

}

传递的String dbName 显示println中 assets 文件夹中存在的db的正确名称,并且数据库是非null并且已预编译,因此我无法确定是错误的原因。 有什么建议吗?

1 个答案:

答案 0 :(得分:1)

我将您的代码复制到我的项目中,并且它可以正常工作。

在loadDatabase()中,

System.out.println("dbName");

将始终打印 dbName 一词。我不确定这是否是资产文件夹中数据库的名称;因为我看不到你对loadDatabase(dbName)的调用,所以我不知道你正在使用什么值。

这是我直接从我的应用程序调用代码的方式:

    String dbName = "itr";
    System.out.println(dbName);
    DataBaseAdapterNew mDbHelper = new DataBaseAdapterNew(
                    this, dbName);
            mDbHelper.createDatabase();
            mDbHelper.open();

在DatabaseHelper.createDataBase()中,您隐藏了错误条件。如果你想看看导致问题的异常,我可以建议

public void createDataBase() throws IOException {
    // If database not exists copy it from the assets

    boolean mDataBaseExist = checkDataBase();
    if (!mDataBaseExist) {
        this.getReadableDatabase();
        this.close();
        try {
            // Copia il database dalla cartella assests
            copyDataBase();
            Log.e(TAG, "createDatabase database created");
        } catch (IOException mIOException) {
            Log.e(TAG, mIOException.toString());
            throw mIOException;
        }
    }
}

打印了异常

  

java.io.FileNotFoundException:itr UnableToCreateDatabase

我将现有数据库复制到/ assets / itr中,并且我的数据库已正确创建。