Tôi là người mới sử dụng toàn bộ Android SQLite. Đây là những gì tôi có:Tệp DB trong Thư mục nội dung. Nó sẽ được cập nhật?
- Tôi có
db.sqlite
trong thư mụcassets
. - Mục đích của db là CHỈ ĐỌC. Người dùng sẽ không viết thư cho nó.
- Khi ứng dụng được cập nhật,
db.sqlite
sẽ được thay thế thành db mới (tôi sẽ xóa tệp cũ khỏi dự án và thêm tệp mới).
Những gì tôi quan tâm là:
- sẽ file db cũ bị xóa? (đó là những gì tôi muốn, thay thế cái cũ bằng cái mới)
- Tại sao hỏi? Bởi vì khi tôi gỡ lỗi ứng dụng của mình, mỗi khi tôi cập nhật tệp db, tôi cần phải gỡ cài đặt ứng dụng khỏi thiết bị để buộc cập nhật. Người dùng có cần phải làm như vậy khi họ cập nhật ứng dụng của tôi từ cửa hàng trò chơi không? Tôi sợ điều đó.
- Điều này có bị ảnh hưởng bởi cách tôi triển khai onCreate(SQLiteDatabase) và onUpgrade(SQLiteDatabase, int, int) không?
- Nếu có, cách thích hợp để triển khai chúng đáp ứng yêu cầu của tôi là gì?
Đây là cách tôi mở rộng lớp SQLiteOpenHelper. Tôi đã theo một hướng dẫn tôi tìm thấy trên internet:
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
Mã của bạn là đơn giản hơn nhiều so với tôi. Tôi hy vọng nó hoạt động. Mặc dù tôi có một vấn đề trước khi thử nghiệm nó: Trong 'initialize()', bạn chỉ cần xóa db cũ nếu nó tồn tại và phiên bản khác. Bạn có giả sử tạo một cái mới không? – iTurki
Có "if (! DatabaseExists()) {createDatabase();}" sau nó. Nó tạo ra db nếu nó bị xóa. Tất nhiên nó có thể được viết lại để lưu kiểm tra này. – biegleux
Tôi không chú ý đến điều đó. Nghĩ rằng đó là một phần 'khác'! Tôi đoán việc triển khai của bạn sẽ hoạt động. Cảm ơn :) – iTurki