一個Android應用給用戶的第一印象非常重要,除了要有好的創意和美觀的界面,性能也是很關鍵的部分,本文討論的就是第一次啟動的速度問題。 Android應用的啟動過程不能讓用戶等待太長時間,個人覺得最好控制在3秒之內。一般來說,內容的初始化是影響Android應用第一次啟動速度的主要因素之一,尤其是創建數據庫並插入一定數量的初始記錄,對於這種問題,最好的辦法莫過於在首次初始化時導入靜態數據庫。
在Android中導入靜態數據庫很簡單,首先將准備好的靜態數據庫文件放到Android工程的res目錄中的raw子目錄下面,如果沒有這個子目錄的話就手動創建該目錄,然后在應用的初始化階段通過類似下面的代碼將數據庫文件拷貝到特定的目錄下面,假設Android應用的包名是com.test,那么大部分情況下該應用默認的數據庫文件位於/data/data/com.test/databases目錄下面。
String dbDirPath = "/data/data/com.test/databases";
File dbDir = new File(dbDirPath);
if(!dbDir.exists()) // 如果不存在該目錄則創建
dbDir.mkdir();
// 打開靜態數據庫文件的輸入流
InputStream is = context.getResources().openRawResource(R.raw.data);
// 打開目標數據庫文件的輸出流
FileOutputStream os = new FileOutputStream(dbDirPath+"/data.db");
byte[] buffer = new byte[1024];
int count = 0;
// 將靜態數據庫文件拷貝到目的地
while ((count = is.read(buffer)) > 0) {
os.write(buffer, 0, count);
}
is.close();
os.close();
以最近完成的一個應用來看,采用導入靜態數據庫的方式后,第一次啟動時間從將近4秒變成了1秒,效果還是很明顯的。
不過,這種方式是假定所有Android設備的應用安裝目錄是相同的,而且數據庫文件的目錄都是/data/data/包名/databases,但是Android的文檔中並沒有明確規定所有設備具有此種目錄結構,所以將靜態數據庫文件拷貝到一個事先定死的目錄的做法還是有一定危險性的。更好的做法是使用Android系統提供的API去解決這個問題,總之,我們要避免的就是使用固定目錄,下面是更好的拷貝過程:
// 打開靜態數據庫文件的輸入流
InputStream is = context.getResources().openRawResource(R.raw.data);
// 通過Context類來打開目標數據庫文件的輸出流,這樣可以避免將路徑寫死。
FileOutputStream os = context.openFileInput("data.db");
byte[] buffer = new byte[1024];
int count = 0;
// 將靜態數據庫文件拷貝到目的地
while ((count = is.read(buffer)) > 0) {
os.write(buffer, 0, count);
}
is.close();
os.close();
最終的數據庫文件將位於/data/data/com.data/files目錄下,需要注意的是,使用Context類的openOrCreateDatabase方法或者SQLiteOpenHelper工具類時,不能再傳遞數據庫的名稱作為參數,而是要把數據庫文件的全路經傳遞給它們。