2012-03-02 4 views
0

예외 :Android에서 SQLiteDatabase 헬퍼를 설정하는 올바른 방법은 무엇입니까?

CREATE TABLE android_metadata failed 
Failed to setLocale() when constructing, closing the database 
android.database.sqlite.SQLiteException: database is locked 

내 애플 onUpgrade()가 호출되는 경우를 제외하고는 잘 작동하고 더 DB 문제가 없습니다.

onUpgrade가 자동으로 호출되면 아래의 CarManager 클래스를 사용하여 업그레이드에 필요한 데이터 조작을 시도합니다. db가 잠겨 있기 때문에 실패합니다.

public class DbHelper extends SQLiteOpenHelper { 

    private Context context; 

    //Required constructor 
    public DbAdapter(Context context) 
    { 
     super(context, "my_db_name", null, NEWER_DB_VERSION); 
     this.context = context; 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 
    { 
     overrideDB = db; 
     CarManager.migrateDataForOnUpgrade(context); 
    } 
} 


public class CarManager { 

    DbHelper dbHelper; 

    public CarManager(Context context) 
    { 
     dbHelper = new DbHelper(context); 
    } 

    public void addCar(String make, String model) 
    { 
     ContentValues contentValues = new ContentValues(); 
     contentValues.put("make", make); 
     contentValues.put("model", model); 

     SQLiteDatabase db = dbHelper.getWritableDatabase(); 
     db.insert("car", null, contentValues); 
     db.close(); 
    } 

    public static void migrateDataForOnUpgrade() 
    { 
     //Code here that migrates data when onUpgrade() is called 
     //Db lock happens here 
    } 
} 

모든 :

이 할 수있는 일상적인 일해야처럼이 것 때문에, 내가 제대로 다음 코드 (두 개의 클래스는 다음과 도우미와 테이블 관리자)를 구조화되어서는 안 보인다 아이디어? 사람이이 테이블 관리자 (예 : dao)를 다르게 설정합니까?

편집 : Google 팀 @ Android 개발자 팀과 이야기를 나누었습니다. onUpgrade3은 결코 구조 변경 (변경)과 같은 것을 할 의도가 없었습니다. 그래서 예, 많은 예제에서 사용해야하는 해킹이있는 것처럼 보입니다.

+0

호기심을 위해서 OrmLite (http://ormlite.com/)는 DAO 클래스를 설정하는 좋은 방법입니다. – jcxavier

+1

예외 게시 – Jack

+0

예외는 무엇입니까? – drulabs

답변

0

Application 클래스를 확장하여 다음 모델을 사용합니다. 나는 ... 간단하게 다음과 같은 않는 DB 도우미를 사용할 필요가 모든 클래스에 다음에서 모든 다른 앱 구성 요소가 사용하는 내 DB 도우미의 단일 정적 인스턴스 ...

public class MyApp extends Application { 

    protected static MyAppHelper appHelper = null; 
    protected static MyDbHelper dbHelper = null; 

    @Override 
    protected void onCreate() { 
     super.onCreate(); 
     ... 
     appHelper = new MyAppHelper(this); 
     dbHelper = MyAppHelper.createDbHelper(); 
     dbHelper.getReadableDatabase(); // Trigger creation or upgrading of the database 
     ... 
    } 
} 

을 유지

if (MyApp.dbHelper == null) 
    MyApp.appHelper.createDbHelper(...); 
// Code here to use MyApp.dbHelper 
+0

컨텍스트 참조 MyAppHelper.createDbHelper (...)를 전달해야한다고 가정합니다. 예를 들어 Activity 클래스에서 'this'를 전달하면 해당 참조가 부실해 질 수 있다는 인상하에있었습니다. 어떻게 생각해? – Shellum

+1

방금 ​​코드를 확인했습니다. 나는 실제로 애플 리케이션 컨텍스트를 참조를 보유하는 '응용 프로그램 도우미'로 전달합니다. 그런 다음'app helper '에 의해'db 헬퍼'에'createDbHelper()'메소드의 일부로 전달됩니다. 응용 프로그램 컨텍스트에 대한 참조를 유지하는 것의 차이점은 하나의 응용 프로그램 인스턴스 만있을 수 있으며 해당 컨텍스트가 수명 동안 유효하다는 것입니다. 액티비티는 반복해서 생성/파기 될 수 있으며, 주어진 액티비티 클래스의 인스턴스를 여러 개 가질 수 있으므로 POJO가 액티비티 컨텍스트를 유지하는 것이 결코 좋지 않습니다. – Squonk

관련 문제