9

我有一个使用 sqlite db 的应用程序,在第一次安装时我检查是否存在数据库文件夹或 db 文件如果不调用 updateDB 函数。但在某些情况下,例如 Galaxy Note 10.1 它给了我错误。

负载 ;

    this.dhn = DataHelper.getDataHelper(this);

    File directory = new File(Environment.getDataDirectory() + File.separator + "data" + File.separator + "XXX" + File.separator + "databases");
    if(!directory.exists())
    {
        directory.mkdirs();
        updateDB();
    }

    try {
        androidCheckout = this.dhn.Guid();

        if(this.dhn.getSettings("dbVersion") == null || Integer.parseInt(this.dhn.getSettings("dbVersion")) != Version || !this.dhn.isTableExists("UserInfo"))
        {
            updateDB(); 
        }
    }
    catch (SQLiteException e)
    {               
    try {
            updateDB();
            androidCheckout = this.dhn.Guid();
        }
    catch (SQLiteException e11)
        {   
            ManuelYukle();
        }

    }



  public void updateDB()
    {
      this.dhn.close();

        try {
            InputStream myInput;

                myInput = getAssets().open("XXX.db");

            // Path to the just created empty db
            String outFileName = "/data/data/XXX/databases/"
                    + "XXX.db";

            // Open the empty db as the output stream
            FileOutputStream 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);
            }

            myOutput.flush();
            myOutput.close();
            myInput.close();
            buffer = null;
            outFileName = null;
            this.dhn.close();
            this.dhn = null;
            this.dhn = DataHelper.getDataHelper(this); <<<<<<<< HERE IT CRUSHS
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    }

DBHELPER 课程 >

    private static DataHelper singleton;

    public static DataHelper getDataHelper(Context context) {
            if (singleton == null) {
                    singleton = new DataHelper(context);
                    OpenHelper openHelper = new OpenHelper(singleton.context);
                    singleton.db = openHelper.getWritableDatabase();
            }
            if(!singleton.db.isOpen()){
                    OpenHelper openHelper = new OpenHelper(singleton.context);
                    singleton.db = openHelper.getWritableDatabase();
            }
            singleton.context = context;
            return singleton;
    }

    private DataHelper(Context context) {
        this.context = context;
}

错误日志文件 >

12-09 19:11:15.772: I/SqliteDatabaseCpp(6271): sqlite returned: error code = 11, msg = database corruption at line 48171 of [ed759d5a9e], db=/data/data/XXX/databases/XXX_db
12-09 19:11:15.772: I/SqliteDatabaseCpp(6271): sqlite returned: error code = 11, msg = database disk image is malformed, db=/data/data/XXX/databases/XXX_db
12-09 19:11:15.772: E/SqliteDatabaseCpp(6271): sqlite3_exec - Failed to set synchronous mode = 1(Normal) 
12-09 19:11:15.772: I/SqliteDatabaseCpp(6271): sqlite returned: error code = 11, msg = database corruption at line 48171 of [ed759d5a9e], db=/data/data/XXX/databases/XXX_db
12-09 19:11:15.772: I/SqliteDatabaseCpp(6271): sqlite returned: error code = 11, msg = database disk image is malformed, db=/data/data/XXX/databases/XXX_db
12-09 19:11:15.772: E/SqliteDatabaseCpp(6271): CREATE TABLE android_metadata failed
12-09 19:11:15.777: E/DefaultDatabaseErrorHandler(6271): Corruption reported by sqlite on database: /data/data/XXX/databases/XXX.db
12-09 19:11:15.782: E/DefaultDatabaseErrorHandler(6271): deleting the database file: /data/data/XXX/databases/XXX.db
4

2 回答 2

3

database disk image is malformed我在更新自身时尝试访问数据库时遇到了同样的问题。所以,我按照下面的方式。

  1. DataBaseHelper

    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import android.content.Context;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteException;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.util.Log;
    
    public class DataBaseHelper extends SQLiteOpenHelper {
    
            private static final String TAG = DataBaseHelper.class.getSimpleName();
            private static String DB_PATH = "/data/data/YOUR_PACKAGE/databases/";
            private static String DB_NAME = "XXX";
            private SQLiteDatabase mDataBase;
            private final Context mContext;
    
            public DataBaseHelper(Context context) {
                super(context, DB_NAME, null, 1);
                DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
                this.mContext = context;
            }
    
            public void createDataBase() throws IOException {
                boolean mDataBaseExist = checkDataBase();
                if (!mDataBaseExist) {
                    this.getReadableDatabase();
                    try {
                        copyDataBase();
                    } catch (IOException mIOException) {
                        throw new Error("ErrorCopyingDataBase");
                    }
                }
            }
    
        private boolean checkDataBase() {
            SQLiteDatabase mCheckDataBase = null;
            try {
                String mPath = DB_PATH + DB_NAME;
                File pathFile = new File(mPath);
                if(pathFile.exists()) {
                    mCheckDataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.NO_LOCALIZED_COLLATORS);
                }
            } catch (SQLiteException mSQLiteException) {
                Log.e(TAG, "DatabaseNotFound " + mSQLiteException.toString());
            }
    
            if (mCheckDataBase != null) {
                mCheckDataBase.close();
            }
            return mCheckDataBase != null;
        }
    
        private void copyDataBase() throws IOException {
            final InputStream mInput = mContext.getAssets().open(DB_NAME);
            final 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 {
            final String mPath = DB_PATH + DB_NAME;
            mDataBase = SQLiteDatabase.openDatabase(mPath, null,
            SQLiteDatabase.NO_LOCALIZED_COLLATORS);
            return mDataBase != null;
        }
    
        @Override
        public synchronized void close() {
            if (mDataBase != null)
                mDataBase.close();
            super.close();
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {}
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
    }
    
  2. DBAdapter

    public class DBAdapter {
    
        private static final String TAG = DBAdapter.class.getSimpleName();
        private final Context mContext;
        private SQLiteDatabase mDb;
        private final DataBaseHelper mDbHelper;
    
        public DBAdapter(Context context) {
            this.mContext = context;
            mDbHelper = new DataBaseHelper(mContext);
        }
    
        public DBAdapter createDatabase() throws SQLException {
            try {
                mDbHelper.createDataBase();
            } catch (IOException mIOException) {
                throw new Error("UnableToCreateDatabase");
            }
            return this;
        }
    
        public DBAdapter open() throws SQLException {
            try {
                mDbHelper.openDataBase();
                mDbHelper.close();
                mDb = mDbHelper.getReadableDatabase();
            } catch (SQLException mSQLException) {
                Log.e(TAG, mSQLException.toString());
                throw mSQLException;
            }
            return this;
        }
    
        public void close() {
            mDbHelper.close();
        }
    }
    
  3. Abhan扩展应用类

    public class Abhan extends Application {
    
        public static final String TAG = Abhan.class.getSimpleName();
        public static final boolean DEBUG = true;
        private int androidVersion = 4;
        private DBAdapter dbAdapter = null;
    
        @Override
        public void onCreate() {
            super.onCreate();
            setAndroidVersion(android.os.Build.VERSION.SDK_INT);
    
            if(dbAdapter == null) {
                dbAdapter = new DBAdapter(getBaseContext());
                dbAdapter.createDatabase();
            }
        }
    
        public int getAndroidVersion() {
            return androidVersion;
        }
    
        public void setAndroidVersion(int androidVersion) {
            this.androidVersion = androidVersion;
        }
    
        public DBAdapter getDBInstatnce() {
            dbAdapter.open();
            return dbAdapter;
        }
    
        public void closeDataBase() {
            dbAdapter.close();
            if(DEBUG) {
                android.util.Log.d(TAG, "DataBase closed.");
            }
        }
    }
    
  4. 在你的AndroidManifest, 声明Abhan

    <application
        android:name=".Abhan"
        android:allowBackup="false"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
    
  5. 在 Your中,使用ClassActivity访问您的数据库Application

    private Abhan abhan;
    

onCreate

    abhan = (Abhan) this.getApplication();

现在像这样访问您的数据库事务方法。

   int currentDay = abhan.getDBInstatnce().getCurrentDay();

在这里,abhan.getDBInstatnce()返回您的Database实例,它是整个应用程序中的单个实例,并且getCurrentDay()是我的方法,在DBAdpater其中声明返回当前日期。

我希望这个可以解决你的问题。谢谢。

于 2013-05-03T04:09:24.130 回答
1

我在使用预填充数据库时遇到了类似的问题。我就是这样解决的。

问题出在 sqlite 数据库中,我认为这是 sqlite3 旧版本中的错误,也许是 3.6 之前的版本。我所做的是,我用sqlite3 v3.7.11重新创建了数据库 ,它就像一个魅力 - 而且,不要忘记创建android_metadata 表

那时它对我有用,我希望这会对你有所帮助。

于 2013-05-07T06:51:26.763 回答