當初始資料庫需含多量資料時, 若再程式第一次啟動才建立資料庫與初始值那會耗掉不少時間
此時就需要是先建好初始資料庫然後與程式一起發佈,讓程式一開始就直接使用該資料庫以節省時間
參考做法如下
- 需將已有之資料庫檔放置於專案 assets 目錄下
- 在必要位置中呼叫 createDataBase() 如activity onCreate 加入如下程式碼
@Override
public void onCreate(Bundle savedInstanceState) {
.....
mOpenHelper = new DatabaseHelper(this);
try {
mOpenHelper.createDataBase();
} catch (IOException e) { e.printStackTrace(); }
}
DatabaseHelper class 參考程式碼
public class DatabaseHelper extends SQLiteOpenHelper {
//修改為實際 package 名稱 "/data/data/<<package name>>/databases/"
private static String DB_PATH = "/data/data/com.eoeAndroid.SQLite/databases/";
private static final String DB_NAME = "dbfortest.db";
private static final int DATABASE_VERSION = 1;
private final Context myContext;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.myContext = context;
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) { // do nothing - database already exist
} else {
this.getReadableDatabase();//此呼叫一定要,否則無法複製,至於為何需要還需深入了解
try {
copyDataBase();
} catch (IOException e) {
throw new Error("資料庫複製失敗");
}
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
} catch (Exception e) {
// database does't exist yet.
// throw new Error("Database does't exist yet.");
}
if (checkDB != null) { checkDB.close(); }
return checkDB != null ? true : false;
}
/**
* 複製預設的 資料庫檔 (本地 assets目錄)到 system 的資料庫目錄下
* /data/data/com.eoeAndroid.SQLite/databases/
* */
private void copyDataBase() throws IOException {
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
String outFileName = DB_PATH + DB_NAME;
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);
}
myOutput.flush();
myOutput.close();
myInput.close();
}
@Override
public void onCreate(SQLiteDatabase db) { //僅會再第一次啟動程式時執行,以後就不會再動作 }
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}
使用此方式, 實務上並非所有手機都可適用,原因為何尚不知? 權限or空間?