2013-03-24 43 views
20

私はSQLiteデータベースを作成しようとしました。しかし私は私のonCreateメソッドが呼び出されていないことを発見しました!SQLiteOpenHelperのonCreateメソッドが呼び出されたときは?

onCreateメソッドの最初にLogCatにメッセージを送信しています。

(スーパー)コンストラクタは、onCreateメソッドを呼び出します。そうですか?

マイコード:

import android.database.sqlite.SQLiteOpenHelper; 
import android.database.sqlite.SQLiteDatabase; 
import android.content.Context; 
import android.database.Cursor; 
import android.content.ContentValues; 
import android.util.Log; 

public class DatabaseHandler extends SQLiteOpenHelper { 
    // Static Constants 
    /*** Database details ***/ 
    // Database version 
    private static final int DATABASE_VERSION   = 1; 

    // Database name 
    private static final String DATABASE_NAME   = "database_name"; 

    /*** Database Tables ***/ 
    /** Events **/ 
    // Event table 
    private static final String TABLE_EVENT    = "event"; 

    // Event table columns 
    private static final String COLUMN_EVENT_EID  = "_eid"; 

    private static final String COLUMN_EVENT_CREATION_DATE = "creation_date"; 

    private static final String COLUMN_EVENT_TITLE  = "title"; 
    private static final String COLUMN_EVENT_ICON  = "icon"; 

    public DatabaseHandler(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 
     Log.e("MyApp", "onCreate invoked"); 
     // Tables creation queries 
     String CREATE_EVENT_TABLE = "create table " + TABLE_EVENT + "(" + COLUMN_EVENT_EID + " integer primary key, " 
       + COLUMN_EVENT_CREATION_DATE + " text, " 
       + COLUMN_EVENT_TITLE + " text, " 
       + COLUMN_EVENT_ICON + " text)"; 

     // Creating tables 
     db.execSQL(CREATE_EVENT_TABLE); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     Log.e("MyApp", "onUpgrade invoked"); 
     db.execSQL("DROP TABLE IF EXISTS " + TABLE_EVENT); 
    } 
} 

MainActivityコード:

import android.os.Bundle; 
import android.app.Activity; 
import android.view.Menu; 

public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     DatabaseHandler db = new DatabaseHandler(this); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

} 

答えて

2

実際のデータベースが存在しない場合にのみ、(スーパー)コンストラクタがonCreateメソッドを呼び出します。 からhttp://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#onCreate%28android.database.sqlite.SQLiteDatabase%29

データベース作成とバージョン管理を管理するヘルパークラス。

あなたがのonCreate(SQLiteDatabase)、 ONUPGRADE(SQLiteDatabase、int型、int型)および任意 開く時(SQLiteDatabase)を実装するサブクラスを作成し、このクラスはそれがない場合は、作成し、それが存在する場合 データベースを開くの面倒を見ますそうでない場合は としてアップグレードしてください。公式文書として

1

は "getWritableDatabase()、述べています。これが呼び出された最初の時間を作成し、および/または読み取りと書き込みに使用されるデータベースを開く、データベースが開かれ、のonCreate(SQLiteDatabase )、onUpgrade(SQLiteDatabase、int、int)および/またはonOpen(SQLiteDatabase)が呼び出されます。

正常に開くと、データベースがキャッシュされるため、データベースに書き込む必要があるたびにこのメソッドを呼び出すことができます。 (データベースが不要になったときにclose()を呼び出すようにしてください)。不正なアクセス権やディスクがいっぱいの場合、このメソッドは失敗する可能性がありますが、

http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html#getWritableDatabase()

2

私は、論理の流れを明確にしましょう。ここには遅延初期設定という概念があります。

DatabaseHandlerの(スーパー)コンストラクタは、onCreateメソッドを呼び出しません。 DatabaseHandlerコンストラクタを呼び出すと、コンテキスト、データベース名、データベースを作成するファクトリ、データベースバージョン、およびデータベースエラーハンドラが初期化されます。

getWritableDatabase()>getDatabaseLocked()> - SQLiteDatabase.create()

OR

getReadableDatabase()>getDatabaseLocked()> - SQLiteDatabase.create ()

回答:データベースが正常に作成された後、次回も設定が変更されます。getReadableDatabase()またはgetWritableDatabase()getDatabaseLocked()となり、onCreate(db)メソッドがgetDatabaseLocked()になります。

enter image description here

説明:

上記SQLiteDatabase.create()方法は、ディスクにSQLiteDatabaseを作成する責任があります。

しかし、遅延初期化のプロセス(つまり、すべての準備が整ったわけではありません。必要な場合は実行時にこれらのオブジェクトが作成されます)は、多くのif..elseステートメントを使用しました。

getDatabaseLocked()の本文が表示されている場合は、以下のとおりです。 [あなたがgetDatabaseLocked()の体内にonCreate()方法を検索することができます]

private SQLiteDatabase getDatabaseLocked(boolean writable) { 
     if (mDatabase != null) { 
      if (!mDatabase.isOpen()) { 
       // Darn! The user closed the database by calling mDatabase.close(). 
       mDatabase = null; 
      } else if (!writable || !mDatabase.isReadOnly()) { 
       // The database is already open for business. 
       return mDatabase; 
      } 
     } 

     if (mIsInitializing) { 
      throw new IllegalStateException("getDatabase called recursively"); 
     } 

     SQLiteDatabase db = mDatabase; 
     try { 
      mIsInitializing = true; 

      if (db != null) { 
       if (writable && db.isReadOnly()) { 
        db.reopenReadWrite(); 
       } 
      } else if (mName == null) { 
       db = SQLiteDatabase.create(null); 
      } else { 
       try { 
        if (DEBUG_STRICT_READONLY && !writable) { 
         final String path = mContext.getDatabasePath(mName).getPath(); 
         db = SQLiteDatabase.openDatabase(path, mFactory, 
           SQLiteDatabase.OPEN_READONLY, mErrorHandler); 
        } else { 
         db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ? 
           Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0, 
           mFactory, mErrorHandler); 
        } 
       } catch (SQLiteException ex) { 
        if (writable) { 
         throw ex; 
        } 
        Log.e(TAG, "Couldn't open " + mName 
          + " for writing (will try read-only):", ex); 
        final String path = mContext.getDatabasePath(mName).getPath(); 
        db = SQLiteDatabase.openDatabase(path, mFactory, 
          SQLiteDatabase.OPEN_READONLY, mErrorHandler); 
       } 
      } 

      onConfigure(db); 

      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(); 
       } 
      } 

      onOpen(db); 

      if (db.isReadOnly()) { 
       Log.w(TAG, "Opened " + mName + " in read-only mode"); 
      } 

      mDatabase = db; 
      return db; 
     } finally { 
      mIsInitializing = false; 
      if (db != null && db != mDatabase) { 
       db.close(); 
      } 
     } 
    } 

に注意してください、getDatabaseLocked()方法の体内に..他の例であれば非常に多くがあります。これらのif..el casesは現在の環境(設定)を決定し、現在の環境に基づいて、必要なものを初期化/設定するための適切なメソッドを呼び出します。また

、ノート:あなたのDatabaseHandlerSQLiteOpenHelperを実装したクラス)ですべてのコールバックメソッドはgetDatabaseLocked()体内に呼ばれています。

ソースコードSQLiteOpenHelper.javahttps://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/database/sqlite/SQLiteOpenHelper.java

ソースコードSQLiteDatabase.javahttps://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/database/sqlite/SQLiteDatabase.java

フォローするサンプル:https://github.com/uddhavgautam/SQLiteBasicSample

関連する問題