2012-11-16 4 views
1

오프라인으로 작성한 데이터베이스가 미리 채워져 있으며 assets/ 디렉토리에 저장하십시오. SQLiteOpenHelper.onCreate()이 호출 될 때 복사하려고하는데 심각한 문제가 발생합니다.SQLiteOpenHelper에서 자산을 복사 할 수 없습니다.

public void onCreate(SQLiteDatabase db) { 
    importAssets(); 
} 

나는이처럼 내 코드를 작성할 때, 나는 일관 이후 데이터베이스에서 데이터를 가져 오기 위해 노력 그런 테이블 오류가 발생하지 않습니다. 나는 약간의 주위에 일 처리했고, 예를 들어, SQL onCreate()에 문뿐만 아니라 importAssets()에 대한 호출을 삽입 시작 :

public void onCreate(SQLiteDatabase db) { 
    importAssets(); 
    db.execSQL("CREATE TABLE main_table (some_col);"); 
} 

을 내가 응용 프로그램을 실행할 때 지금, 나는이 열 문제를 얻을 발견되지 오류가 발생합니다 (위의 스키마가 DB 액세스 코드가 기대하는 것과 일치하지 않는 경우 많은 열이 누락됩니다. 앱의 두 번째 실행에서 android_metatdata이 손상되어 모든 것이 지옥으로 빠져 나옵니다. importAssets() 전화와 마찬가지로 불행한 결과가 발생합니다.

그래서 제가 생각하기에 파일 복사가 importAssets()은 본질적으로 onCreate()에 의해 잘립니다. 내가 맞습니까? SQL을 직접 사용하여 onCreate()에 DB를 만드는 유일한 방법입니까? assets/에서 기성 DB를 복사하는 데이 기능을 사용할 수 없습니까?

Log() 호출을 사용하여 importAssets()이 올바르게 실행되고 있음을 확인했습니다. 여기에 전체 기능입니다 : 내가 elsewhere 나는 SQLiteOpenHelper 생성자 내부의 파일 복사를 할 제안을 본 적이

private void importAssets() throws IOException 
{ 
    AssetManager am = mCtx.getAssets(); 
    InputStream in = am.open(DB_NAME); 
    FileOutputStream out; 
    byte[] buffer = new byte[1024]; 
    int len; 
    File db; 

    db = new File(DB_DIR + "/" + DB_NAME); 

    // copy the DB from assets to standard DB dir created above 
    out = new FileOutputStream(db); 
    while ((len = in.read(buffer)) > 0) 
    { 
     out.write(buffer, 0, len); 
    } 

    out.flush(); 
    out.close(); 
    in.close(); 
    if (!db.exists()) 
    { 
     Log.e(TAG, DB_DIR + "/" + DB_NAME + " does not exist"); 
    } 
} 

,하지만 그게 내가 수동으로부터 importAssets()에서 파일의 존재를 확인해야 할 것이다 의미 생성자는 DB를 사용할 때마다 호출됩니다. 또한 onCreate()은 내가하고 싶은 일에 효과적으로 쓸모가 없습니다. 그러나 나는 그것을 피할 방법이 없습니다.

답변

1

나는 이제 나의 의혹이 옳았다 고 확신했다. onCreate() 함수가 SQLiteOpenHelper이면 수퍼 클래스 생성자에 대한 호출의 name 매개 변수에 지정된 DB 파일이 만들어집니다. 그런 다음 다양한 DB 라이브러리를 사용하여 onCreate() 함수 내에서이 DB 파일을 수정 (테이블, 데이터, 테이블 변경 등) 할 수 있습니다. 어딘가에서 파일을 복사하면 잘릴 것입니다..

나는 이것이 어떻게하고 왜하는지 알지 못하지만, onCreate()은 데이터베이스를 그대로 복사하여 쓸모 없게 만든다. assets/ 내가 필요한 것이다. 나는 importAssets()을 생성자로 옮기고 이미 존재한다면 그것을 덮어 쓰지 않기 위해 적절한 체크를 덧붙였다. onCreate()에 아무것도 없다면 다른 곳에서 벌어지고있는 일을 혼란스럽게하는 것처럼 보이지 않습니다.

나는 SQLiteOpenHelper이 실제로 SQLite 스크립트를 실행할 수 있어야한다고 생각합니다. 이런 식으로 필자는 자바 코드에 SQL의 긴 덩어리를 하드 코딩 할 필요가 없다. 정말로 내가 원하는 것은 DB 설정을 얻는 것이다.