나만의 작품에 스레딩이 있습니까? 어떤 코드가 mSQLDBreader
을 다른 방법으로 재설정 중일 수 있습니다. 아마도이 스레드는 사용하기 전에 가끔씩 실행되고 mSQLDBreader의 값을 삭제합니다.
2.3.x를 실행하는 에뮬레이터에서 목격 한 적이 있습니까?
Google의 getReadableDatabase 코드를 살펴본 결과 null이 반환 될 수있는 방법이 표시되지 않습니다. 당신이 관심이 있다면 피투성이의 세부 사항은 아래 있습니다. 내가 본 것에 기반하여 코드의 멀티 스레딩 버그 나 테스트 한 장치 제조업체의 안드로이드 코드에 대한 사용자 정의로 인한 버그가 의심 스러울 것입니다 (그럴만한 경우 그럴 수도 있습니다).
세부 정보 getReadableDatabase를 통한 모든 경로는 경로를 작성한 후 리턴 오브젝트에서 메소드를 호출합니다. 따라서이 값은 null이 될 수 없습니다. 그렇지 않으면 NPE가 내부에서 제기됩니다.
다음은 getReadableDatabase에 대한 2.3.6 코드 스 니펫입니다. 실제 출처는 grepcode입니다.
public synchronized SQLiteDatabase getReadableDatabase() {
if (mDatabase != null && mDatabase.isOpen()) {
return mDatabase; // The database is already open for business
}
if (mIsInitializing) { /* snip throw ISE */ }
try {
return getWritableDatabase();
} catch (SQLiteException e) {
// snip : throws or falls through below
}
SQLiteDatabase db = null;
try {
mIsInitializing = true;
String path = mContext.getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory, SQLiteDatabase.OPEN_READONLY);
// *** next line calls method on db. NPE would be here if db was null at this point. ***
if (db.getVersion() != mNewVersion) {
// snip throw.
}
onOpen(db);
Log.w(TAG, "Opened " + mName + " in read-only mode");
mDatabase = db;
return mDatabase;
} finally {
// snip : not relevant
}
}
일반적으로 getReadableDatabase는 getWritableDatabase의 결과를 반환합니다. 그는 다음과 같습니다
public synchronized SQLiteDatabase getWritableDatabase() {
if (mDatabase != null && mDatabase.isOpen() && !mDatabase.isReadOnly()) {
return mDatabase; // The database is already open for business
}
if (mIsInitializing) {
throw new IllegalStateException("getWritableDatabase called recursively");
}
// snip comment about locking
boolean success = false;
SQLiteDatabase db = null;
if (mDatabase != null) mDatabase.lock();
try {
mIsInitializing = true;
if (mName == null) {
db = SQLiteDatabase.create(null);
} else {
db = mContext.openOrCreateDatabase(mName, 0, mFactory);
}
int version = db.getVersion(); // ** method called on result!
// snip block that has more method calls and never nulls out db
onOpen(db);
success = true;
return db;
} finally {
// snip
mDatabase = db;
// snip rest of finally block that isn't relevant.
}
}
마지막으로, 이러한 방법뿐만 아니라 SqliteOpenHelper의 close 메소드의 모두 동기화와 태그 것이 중요합니다, 그래서 하나의 방법은 쓰레기 수있는 방법은 없습니다 동시에 이러한 메서드를 호출 할 여러 스레드가있는 경우 다른 상태 .. 사용하기 전에