gpt4 book ai didi

android - Assets 文件夹中的数据库文件。会更新吗?

转载 作者:IT老高 更新时间:2023-10-28 23:10:56 26 4
gpt4 key购买 nike

我是整个 Android SQLite 的新手。这就是我所拥有的:

  • 我的 assets 文件夹中有 db.sqlite
  • 数据库的目的是只读。用户不会写信给它。
  • 当应用更新时,db.sqlite 将被替换为新的数据库(我将从项目中删除旧文件并添加新文件)。

我担心的是:

  • 旧的 db 文件会被删除吗? (这就是我想要的;用新的替换旧的)
    • 为什么要问?因为当我调试我的应用程序时,每次更新 db 文件时,我都需要从设备上卸载应用程序以强制更新。当用户从 Play 商店更新我的应用程序时,他们是否需要这样做?我很害怕。
  • 这是否会受到我的实现方式的影响 onCreate(SQLiteDatabase)onUpgrade(SQLiteDatabase, int, int) ?
    • 如果是,实现它们以满足我的要求的正确方法是什么?

这就是我扩展 SQLiteOpenHelper 的方式类(class)。我按照我在互联网上找到的教程进行操作:

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.Cursor;
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{

//The Android's default system path of your application database.
private static String DB_PATH = "/data/data/com.mydomain.myapp/databases/";
private static String DB_NAME = "db.sqlite";
private SQLiteDatabase myDataBase;
private final Context myContext;

/*
* Constructor
* Takes and keeps a reference of the passed context in order to access to the application assets and resources.
* @param context
**/
public DataBaseHelper(Context context) {

super(context, DB_NAME, null, 1);
this.myContext = context;
}

/**
* Creates a empty database on the system and rewrites it with your own database.
* */
public void createDataBase() throws IOException{

boolean dbExist = checkDataBase();

if(dbExist){
//do nothing - database already exist
Log.i("myapp", "database already exist");
}else{
Log.i("myapp", "database NOT exist");

//By calling this method and empty database will be created into the default system path
//of your application so we are gonna be able to overwrite that database with our database.
this.getReadableDatabase();

try {

copyDataBase();

} catch (IOException e) {

throw new Error("Error copying database");

}
}

}

/**
* Check if the database already exist to avoid re-copying the file each time you open the application.
* @return true if it exists, false if it doesn't
*/
private boolean checkDataBase(){

SQLiteDatabase checkDB = null;

try{
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);

}catch(SQLiteException e){

//database does't exist yet.

}

if(checkDB != null){

checkDB.close();

}

return checkDB != null ? true : false;
}

/**
* Copies your database from your local assets-folder to the just created empty database in the
* system folder, from where it can be accessed and handled.
* This is done by transfering bytestream.
* */
private void copyDataBase() throws IOException{

//Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);

// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;

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

//Close the streams
myOutput.flush();
myOutput.close();
myInput.close();

}

public void openDataBase() throws SQLException{

//Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);

}

@Override
public synchronized void close() {

if(myDataBase != null)
myDataBase.close();

super.close();

}

@Override
public void onCreate(SQLiteDatabase db) {

}

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

}

// My public helper methods to access and get content from the database go here

最佳答案

您不能在 onUpgrade() 中替换数据库,因为在此方法中数据库已在使用中。您必须在数据库打开之前执行此操作,例如在 DatabaseHelper 的构造函数中。由于您不能使用 onUpgrade(),您必须自己管理数据库版本控制。使用 SharedPreferences 是一个很好的方法。您检查您的数据库是否存在(如果它已经从 assets 目录复制)并检查数据库是否存在的版本。现在您可以删除旧数据库并从 assets 复制新数据库。请参阅下面的实现。

要在 assets 中标记您更新的应用程序已使用新数据库发布,只需增加 DATABASE_VERSION 常量。

private static class DatabaseHelper extends SQLiteOpenHelper {

private static final String DATABASE_NAME = "database.db";
private static final int DATABASE_VERSION = 1;
private static final String SP_KEY_DB_VER = "db_ver";
private final Context mContext;

public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
mContext = context;
initialize();
}

/**
* Initializes database. Creates database if doesn't exist.
*/
private void initialize() {
if (databaseExists()) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(mContext);
int dbVersion = prefs.getInt(SP_KEY_DB_VER, 1);
if (DATABASE_VERSION != dbVersion) {
File dbFile = mContext.getDatabasePath(DATABASE_NAME);
if (!dbFile.delete()) {
Log.w(TAG, "Unable to update database");
}
}
}
if (!databaseExists()) {
createDatabase();
}
}

/**
* Returns true if database file exists, false otherwise.
* @return
*/
private boolean databaseExists() {
File dbFile = mContext.getDatabasePath(DATABASE_NAME);
return dbFile.exists();
}

/**
* Creates database by copying it from assets directory.
*/
private void createDatabase() {
String parentPath = mContext.getDatabasePath(DATABASE_NAME).getParent();
String path = mContext.getDatabasePath(DATABASE_NAME).getPath();

File file = new File(parentPath);
if (!file.exists()) {
if (!file.mkdir()) {
Log.w(TAG, "Unable to create database directory");
return;
}
}

InputStream is = null;
OutputStream os = null;
try {
is = mContext.getAssets().open(DATABASE_NAME);
os = new FileOutputStream(path);

byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
os.flush();
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
editor.commit();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

@Override
public void onCreate(SQLiteDatabase db) {
}

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

关于android - Assets 文件夹中的数据库文件。会更新吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11601573/

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