Theo nhận xét từ Gabe Sechan, phương pháp đơn giản nhất là sao chép db từ thư mục nội dung mỗi khi Ứng dụng được khởi động, đó là thay đổi:-
private void createDB(){
boolean dbExist = DBExists();
if(!dbExist){
this.getReadableDatabase();
copyDBFromResource();
}
dbSglite=getReadableDatabase();
}
tới:-
private void createDB(){
copyDBFromResource();
dbSglite=getReadableDatabase();
}
Dường như bạn có thắc mắc về việc bình luận
"Sẽ không sao chép DB mỗi khi hoạt động được bắt đầu."
vâng, nó sẽ (Điều đó có tệ không? - tu từ ).
Tuy nhiên, giả sử bạn đang sử dụng Phiên bản cơ sở dữ liệu, tức là kiểm tra phiên bản trong thư mục nội dung so với phiên bản hiện tại. Về cơ bản, bạn vẫn cần truy cập cơ sở dữ liệu từ thư mục tài sản, vì vậy bạn sẽ kiểm tra một cơ sở dữ liệu này với một cơ sở dữ liệu khác (ít nhất là mở chúng). Vì vậy, vẫn sẽ có một số chi phí.
Một tùy chọn có thể ít chuyên sâu hơn sẽ là kiểm tra sửa đổi lần cuối của tệp nội dung ngày so với ngày của tệp nội dung được sao chép lần cuối trong tùy chọn được chia sẻ. (File
lastModified
phương pháp) Tệp - lastModified.
Một tùy chọn khác, trong một chế độ xem tương tự, sẽ là kiểm tra gói phiên bản so với lần triển khai cuối cùng, lại được lưu trữ trong các tùy chọn được chia sẻ.
Tất nhiên trong cả hai tùy chọn này, việc thay thế cơ sở dữ liệu từ tệp tài sản chỉ xảy ra khi có sự khác biệt (tăng lên).
Ví dụ sử dụng Phiên bản gói
Ví dụ sau (tất cả các thay đổi trong dbHelper lớp) sẽ sao chép Cơ sở dữ liệu từ các phần tử nếu phiên bản gói được tăng lên (hoặc nếu Cơ sở dữ liệu không tồn tại):-
class dbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "questions.db";
private static final int SCHEMA_VERSION = 1;
private static final String SHARED_PREFS = "shared_prefs";
private static final String SHARED_PREFKEY_QUESTIONSDBLASTUPDATED = "spkey_qdblastupdated";
public SQLiteDatabase dbSglite;
private String mDBPath;
private final Context myContext;
public dbHelper(Context context) {
super(context, DATABASE_NAME, null, SCHEMA_VERSION);
this.myContext=context;
this.mDBPath=context.getDatabasePath(DATABASE_NAME).getParent();
}
@Override
public void onCreate(SQLiteDatabase db){
Log.d("ONCREATE","OnCreate Method Called.");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void createDatabase(){
createDB();
}
private void createDB(){
if (isQuestionsDBNew() || (!DBExists())) {
Log.d("COPYFROMASSET", "Copying Questions From Assets");
copyDBFromResource();
setQuestionsDBNew(getPackageVersion());
} else {
Log.d("COPYFROMASSET",
"Questions not copied from Assets - New Questions Check result was " +
Boolean.toString(isQuestionsDBNew()) +
" DB Exists result was " + Boolean.toString(DBExists())
);
}
dbSglite=getReadableDatabase();
}
private boolean DBExists(){
SQLiteDatabase db = null;
try {
String databasePath = myContext.getDatabasePath(DATABASE_NAME).getPath();
db = SQLiteDatabase.openDatabase(databasePath,null, SQLiteDatabase.OPEN_READWRITE);
db.setLocale(Locale.getDefault());
db.setLockingEnabled(true);
db.setVersion(1);
} catch (SQLiteException e) {
Log.e("SqlHelper", "database not found");
}
if (db != null) {
db.close();
}
return db != null;
}
private void copyDBFromResource() {
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = myContext.getAssets().open(DATABASE_NAME);
File databasedir = new File(myContext.getDatabasePath(DATABASE_NAME).getParent());
databasedir.mkdirs();
outputStream = new FileOutputStream(mDBPath+"/"+DATABASE_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length=inputStream.read(buffer))>0){
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
throw new Error("Problem copying database.");
}
}
public void openDataBase() throws SQLException {
String myPath = myContext.getDatabasePath(DATABASE_NAME).getPath();
dbSglite = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
}
private boolean isQuestionsDBNew() {
SharedPreferences prefs = myContext.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE);
long stored_lastused = prefs.getLong(SHARED_PREFKEY_QUESTIONSDBLASTUPDATED,-1);
Log.d("NEWQUESTIONS?", "Result of testing package version " +
String.valueOf(stored_lastused) +
" against " +
String.valueOf( getPackageVersion()) +
" was " + String.valueOf(stored_lastused < getPackageVersion()));
return (stored_lastused < getPackageVersion());
}
private long getPackageVersion() {
PackageInfo pi;
try {
pi = myContext.getPackageManager().getPackageInfo(myContext.getPackageName(),0);
} catch (PackageManager.NameNotFoundException e) {
return -1;
}
Log.d("PACKAGEVERSION", "The version of package " +
myContext.getPackageName() +
" was " +
String.valueOf(pi.versionCode)
);
return pi.versionCode;
}
private void setQuestionsDBNew(long lastused) {
SharedPreferences.Editor editor = myContext.getSharedPreferences(SHARED_PREFS, Context.MODE_PRIVATE).edit();
editor.putLong(SHARED_PREFKEY_QUESTIONSDBLASTUPDATED,lastused);
editor.apply();
}
}
Ghi chú
- Mã dựa rất nhiều vào mã từ câu hỏi. Có:-
- Hai biến lớp bổ sung (hằng số) để xử lý các tùy chọn được chia sẻ.
- Ba phương pháp mới:-
-
isQuestionsDBNew
trả về true nếu phiên bản gói lớn hơn phiên bản lưu trữ trong tùy chọn chia sẻ (không có gì trong tùy chọn chia sẻ dẫn đến -1, vì vậy sẽ nhỏ hơn bất kỳ phiên bản gói nào). -
getPackageVersion
trả về phiên bản gói dài hạn. -
setQuestionsDBNew
cập nhật tùy chọn được chia sẻ hiện hành. - Các thay đổi đối với createDB để kiểm tra sự thay đổi phiên bản gói và sau đó sao chép cơ sở dữ liệu từ các phần tử. Có một kiểm tra bổ sung để xem liệu cơ sở dữ liệu có tồn tại hay không, mặc dù điều này sẽ chỉ cần thiết nếu tệp cơ sở dữ liệu bị xóa. Việc xóa dữ liệu của Ứng dụng sẽ xóa các tùy chọn được chia sẻ, do đó, cơ sở dữ liệu sẽ bị sao chép.
- Mã bao gồm một số ghi nhật ký chẩn đoán mà tôi đã để lại.
- Điều này chưa được thử nghiệm rộng rãi (nghĩa là tôi chưa đi đến mức tăng phiên bản gói).
Kết quả từ ví dụ - Ứng dụng đang được cài đặt:-
01-05 19:46:44.849 26692-26692/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:46:44.850 26692-26692/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:46:44.850 26692-26692/m.com.so48103235_updateprepopdb D/NEWQUESTIONS?: Result of testing package version -1 against 1 was true
01-05 19:46:44.850 26692-26692/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:46:44.850 26692-26692/m.com.so48103235_updateprepopdb D/COPYFROMASSET: Copying Questions From Assets
01-05 19:46:44.855 26692-26692/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
Kết quả từ ví dụ - Lần chạy tiếp theo:-
01-05 19:48:10.375 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.376 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.376 26755-26755/m.com.so48103235_updateprepopdb D/NEWQUESTIONS?: Result of testing package version 1 against 1 was false
01-05 19:48:10.376 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.381 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.381 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.381 26755-26755/m.com.so48103235_updateprepopdb D/NEWQUESTIONS?: Result of testing package version 1 against 1 was false
01-05 19:48:10.382 26755-26755/m.com.so48103235_updateprepopdb D/PACKAGEVERSION: The version of package m.com.so48103235_updateprepopdb was 1
01-05 19:48:10.387 26755-26755/m.com.so48103235_updateprepopdb D/COPYFROMASSET: Questions not copied from Assets - New Questions Check result was false DB Exists result was true
- Thông báo bổ sung do thông báo mở rộng hơn được sử dụng khi báo cáo rằng cơ sở dữ liệu đã không được sao chép lại các phương thức gọi có thêm thông báo nhật ký.