Android中的Sqlite中的onCreate方法和onUpgrade方法的執行時機 分類: Android 2015-06-17 19:56 366人閱讀 評論(0) 收藏

今天在作數據庫升級的時候,遇到一個問題,就是onCreate方法和onUpgrade方法的執行時機的問題,這個當時在操做的時候,沒有弄清楚,非常迷糊,因此寫代碼的時候出現了不少的問題,因此沒辦法就去扒源代碼看了。不過在此以前我講解過一篇關於數據庫升級的文章,可是那裏沒有詳細的講解一下這兩個方法的執行時機,因此這裏就在單獨說一下java

關於數據庫升級的文章:http://blog.csdn.net/jiangwei0910410003/article/details/39670813數據庫

很少說,下面直接進入主題吧:ide

首先咱們看看SQLiteOpenHelper類的源碼:spa

它裏面有一個重要的方法:getDatabaseLocked.net


這裏咱們看到當咱們的mName變量爲null的時候,就會建立一個內存數據庫,數據的生命週期是Application級別的,這個mName就是建立數據庫的文件名。code


固然正常狀況下,咱們都會傳入一個數據庫文件名的,因此這個方法通常不會執行的,那麼就走下面的代碼。下面的代碼就是直接打開一個數據庫。不過咱們看到一個特色,就是建立數據庫和Context有關係呢。咱們看一下Context中的代碼。不過這裏咱們知道Context是一個抽象類,咱們通常會看他的子類ContextImpl實現:對象

主要看一下getDatabasePath方法和openOrCreateDatabase方法:blog

首先來看一下openOrCreateDatabase方法:生命週期

@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
        DatabaseErrorHandler errorHandler) {
    File f = validateFilePath(name, true);
    int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
    if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
        flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
    }
    SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
    setFilePermissionsFromMode(f.getPath(), mode, 0);
    return db;
}
這裏咱們看到其實仍是調用了SQLiteDatabase的openDatabase方法


再來看一下getDatabasePath方法:內存

@Override
public File getDatabasePath(String name) {
    return validateFilePath(name, false);
}


咱們看到這兩個方法都是有一個核心的方法:validateFilePath

private File validateFilePath(String name, boolean createDirectory) {
    File dir;
    File f;

    if (name.charAt(0) == File.separatorChar) {
        String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
        dir = new File(dirPath);
        name = name.substring(name.lastIndexOf(File.separatorChar));
        f = new File(dir, name);
    } else {
        dir = getDatabasesDir();
        f = makeFilename(dir, name);
    }

    if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
        FileUtils.setPermissions(dir.getPath(),
            FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
            -1, -1);
    }

    return f;
}
這個方法其實很簡單,就是經過傳遞過來的數據庫名稱name,而後構建一個數據庫文件File對象返回便可。


那麼上面的幾個方法咱們能夠總結功能:

經過傳遞過來的數據庫名稱name,建立一個File對象,而後獲得數據庫文件的path..傳遞給SQLDatabase的openDatabase方法中,打開數據庫文件


下面咱們繼續來看那個流程:

final int version = db.getVersion();
if (version != mNewVersion) {
    if (db.isReadOnly()) {
        throw new SQLiteException("Can't upgrade read-only database from version " +
                db.getVersion() + " to " + mNewVersion + ": " + mName);
    }

    db.beginTransaction();
    try {
        if (version == 0) {
            onCreate(db);
        } else {
            if (version > mNewVersion) {
                onDowngrade(db, version, mNewVersion);
            } else {
                onUpgrade(db, version, mNewVersion);
            }
        }
        db.setVersion(mNewVersion);
        db.setTransactionSuccessful();
    } finally {
        db.endTransaction();
    }
}
當打開數據庫文件的時候,咱們就開始進行操做了,今天講的內容最主要的就是上面的判斷了:

首先獲取數據庫的當前版本,當版本號爲0的時候,就會執行onCreate方法(當數據庫文件第一次建立的時候版本號就是0)若是版本號不爲0,同時和最新版本號進行比較,若是大於的話,就執行升級操做onUpgrade方法,不然就執行降級onDowngrade方法,不過降級方法實現很簡單:


直接拋出異常,也就是說數據庫不容許降級操做的,這個也符合正常狀況。


好了。經過上面的分析,下面咱們就對這兩個方法作一下總結:

public abstract void onCreate(SQLiteDatabase db);
public abstract void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion);


SQLiteOpenHelper會自動檢測數據庫文件是否存在。若是存在,會打開這個數據庫,在這種狀況下就不會調用onCreate()方法。若是數據庫文件不存在,SQLiteOpenHelper首先會建立一個數據庫文件,而後打開這個數據庫,最後調用onCreate()方法。所以,onCreate()方法通常用來在新建立的數據庫中創建表、視圖等數據庫組建。

也就是說onCreate()方法在數據庫文件第一次建立時調用。


先看看SQLiteOpenHelper類的構造方法再解釋onUpdate()方法什麼時候會被調用。
public SQLiteOpenHelper(Context context,String name,CursorFactory factory,int version);
其中name參數表示數據庫文件名(不包括文件路徑),SQLiteOpenHelper會根據這個文件名建立數據庫文件。version表示數據庫的版本號。若是當前傳入的數據庫版本號比上次建立或升級的版本號高,SQLiteOpenHelper就會調用onUpdate()方法。也就是說,當數據庫第一次建立時會有一個初始的版本號。當須要對數據庫中的表、視圖等組建升級時能夠增大版本號,再從新建立它們。如今總結一下onCreate()和onUpgrade()調用過程。


1.若是數據庫文件不存在,SQLiteOpenHelper在自動建立數據庫後會調用onCreate()方法,在該方法中通常須要建立表、視圖等組件。在建立前數據庫通常是空的,所以不須要先刪除數據庫中相關的組件。
2.若是數據庫文件存在,而且當前版本號高於上次建立或升級的版本號,SQLiteOpenHelper會調用onUpgrade()方法,調用該方法後會更新數據庫的版本號。在onUpgrade()方法中除了建立表、視圖等組件外,還須要先刪除這些相關的組件,所以,在調用onUpgrade()方法前,數據庫是存在的,裏面還原許多數據庫組建。


綜合上述兩點,能夠得出一個結論:

若是數據庫文件不存在,只有onCreate()被調用(該方法在建立數據庫時被調用一次)。若是數據庫文件存在,會調用onUpgrade()方法升級數據庫,並更新版本號。

相關文章
相關標籤/搜索