gpt4 book ai didi

Android Sqlite 单例数据库文件流更新失败

转载 作者:IT王子 更新时间:2023-10-29 06:21:53 24 4
gpt4 key购买 nike

我有一个应用程序使用 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();
}
}

数据库助手类>

    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

最佳答案

当我尝试访问正在更新自身的数据库时,我遇到了同样的问题数据库磁盘镜像格式错误。所以,我按照下面的方式。

  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. 在您的Activity 中,使用Application 类访问您的数据库

    private Abhan abhan;

onCreate

    abhan = (Abhan) this.getApplication();

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

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

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

希望本文能解决您的问题。谢谢。

关于Android Sqlite 单例数据库文件流更新失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13789669/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com